kbx: Initial support for an SQLite backend

* kbx/backend-sqlite.c: New.
* kbx/Makefile.am (keyboxd_SOURCES): Add it.
(keyboxd_CFLAGS, keyboxd_LDADD): Add SQLite flags.
* kbx/backend.h (enum database_types): Add DB_TYPE_SQLITE.
(be_sqlite_local_t): New typedef.
(struct db_request_part_s): Add field besqlite.
* kbx/backend-support.c (strdbtype): Add string for DB_TYPE_SQLITE.
(be_generic_release_backend): Support SQLite.
(be_release_request): Ditto.
(be_find_request_part): Ditto.
(is_x509_blob): Rename to ...
(be_is_x509_blob): this and make global.
* kbx/frontend.c (kbxd_set_database): Detect ".db" suffix and use that
for SQLite.
(kbxd_search): Support SQLite
(kbxd_store): Ditto.
(kbxd_delete): Ditto.
* kbx/frontend.h (kbxd_store_modes): Move to ...
* kbx/keyboxd.h (enum kbxd_store_modes): here.
* kbx/keyboxd.c (main): USe pubring.db for now.  This is a temporary
hack.

* kbx/backend-kbx.c (be_kbx_delete): Remove unused var cert.
--

Take care: This is not finished and in particular filling the database
takes quite long.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-01-02 14:21:12 +01:00
parent a230bac339
commit f4da1455c7
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
9 changed files with 1424 additions and 87 deletions

View File

@ -79,13 +79,16 @@ keyboxd_SOURCES = \
backend.h backend-support.c \
backend-cache.c \
backend-kbx.c \
backend-sqlite.c \
$(common_sources)
keyboxd_CFLAGS = $(AM_CFLAGS) -DKEYBOX_WITH_X509=1 \
$(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS) $(INCICONV)
$(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS) $(SQLITE3_CFLAGS) \
$(INCICONV)
keyboxd_LDADD = $(commonpth_libs) \
$(KSBA_LIBS) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \
$(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) \
$(SQLITE3_LIBS) $(GPG_ERROR_LIBS) \
$(LIBINTL) $(NETLIBS) $(LIBICONV) \
$(resource_objs)
keyboxd_LDFLAGS = $(extra_bin_ldflags)
keyboxd_DEPENDENCIES = $(resource_objs)

View File

@ -434,7 +434,6 @@ 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;
@ -452,6 +451,5 @@ be_kbx_delete (ctrl_t ctrl, backend_handle_t backend_hd, db_request_t request)
err = keybox_delete (part->kbx_hd);
leave:
ksba_cert_release (cert);
return err;
}

1288
kbx/backend-sqlite.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,7 @@ strdbtype (enum database_types t)
case DB_TYPE_NONE: return "none";
case DB_TYPE_CACHE:return "cache";
case DB_TYPE_KBX: return "keybox";
case DB_TYPE_SQLITE: return "sqlite";
}
return "?";
}
@ -87,6 +88,9 @@ be_generic_release_backend (ctrl_t ctrl, backend_handle_t hd)
case DB_TYPE_KBX:
be_kbx_release_resource (ctrl, hd);
break;
case DB_TYPE_SQLITE:
be_sqlite_release_resource (ctrl, hd);
break;
default:
log_error ("%s: faulty backend handle of type %d given\n",
__func__, hd->db_type);
@ -107,6 +111,7 @@ be_release_request (db_request_t req)
{
partn = part->next;
be_kbx_release_kbx_hd (part->kbx_hd);
be_sqlite_release_local (part->besqlite);
xfree (part);
}
}
@ -140,6 +145,15 @@ be_find_request_part (backend_handle_t backend_hd, db_request_t request,
return err;
}
}
else if (backend_hd->db_type == DB_TYPE_SQLITE)
{
err = be_sqlite_init_local (backend_hd, part);
if (err)
{
xfree (part);
return err;
}
}
part->next = request->part;
request->part = part;
}
@ -174,8 +188,8 @@ be_return_pubkey (ctrl_t ctrl, const void *buffer, size_t buflen,
/* Return true if (BLOB/BLOBLEN) seems to be an X509 certificate. */
static int
is_x509_blob (const unsigned char *blob, size_t bloblen)
int
be_is_x509_blob (const unsigned char *blob, size_t bloblen)
{
const unsigned char *p;
size_t n, objlen, hdrlen;
@ -237,7 +251,7 @@ be_ubid_from_blob (const void *blob, size_t bloblen,
{
gpg_error_t err;
if (is_x509_blob (blob, bloblen))
if (be_is_x509_blob (blob, bloblen))
{
/* Although libksba has a dedicated function to compute the
* fingerprint we compute it here directly because we know that

View File

@ -32,7 +32,8 @@ enum database_types
{
DB_TYPE_NONE, /* No database at all (unitialized etc.). */
DB_TYPE_CACHE, /* The cache backend (backend-cache.c). */
DB_TYPE_KBX /* Keybox type database (backend-kbx.c). */
DB_TYPE_KBX, /* Keybox type database (backend-kbx.c). */
DB_TYPE_SQLITE /* SQLite type database (backend-sqlite.c).*/
};
@ -43,6 +44,11 @@ struct backend_handle_s;
typedef struct backend_handle_s *backend_handle_t;
/* Private data for sqlite requests. */
struct be_sqlite_local_s;
typedef struct be_sqlite_local_s *be_sqlite_local_t;
/* Object to store backend specific database information per database
* handle. */
struct db_request_part_s
@ -52,9 +58,12 @@ struct db_request_part_s
/* Id of the backend instance this object pertains to. */
unsigned int backend_id;
/* The handle used for a KBX backend or NULL. */
/* Local data for a KBX backend or NULL. */
KEYBOX_HANDLE kbx_hd;
/* Local data for a sqlite backend. */
be_sqlite_local_t besqlite;
/* For the CACHE backend the indices into the bloblist for each
* index type. */
struct {
@ -106,6 +115,7 @@ gpg_error_t be_find_request_part (backend_handle_t backend_hd,
gpg_error_t be_return_pubkey (ctrl_t ctrl, const void *buffer, size_t buflen,
enum pubkey_types pubkey_type,
const unsigned char *ubid);
int be_is_x509_blob (const unsigned char *blob, size_t bloblen);
gpg_error_t be_ubid_from_blob (const void *blob, size_t bloblen,
enum pubkey_types *r_pktype, char *r_ubid);
@ -148,4 +158,24 @@ gpg_error_t be_kbx_delete (ctrl_t ctrl, backend_handle_t backend_hd,
db_request_t request);
/*-- backend-sqlite.c --*/
gpg_error_t be_sqlite_add_resource (ctrl_t ctrl, backend_handle_t *r_hd,
const char *filename, int readonly);
void be_sqlite_release_resource (ctrl_t ctrl, backend_handle_t hd);
gpg_error_t be_sqlite_init_local (backend_handle_t backend_hd,
db_request_part_t part);
void be_sqlite_release_local (be_sqlite_local_t ctx);
gpg_error_t be_sqlite_search (ctrl_t ctrl, backend_handle_t hd,
db_request_t request,
KEYDB_SEARCH_DESC *desc, unsigned int ndesc);
gpg_error_t be_sqlite_store (ctrl_t ctrl, backend_handle_t backend_hd,
db_request_t request, enum kbxd_store_modes mode,
enum pubkey_types pktype,
const unsigned char *ubid,
const void *blob, size_t bloblen);
gpg_error_t be_sqlite_delete (ctrl_t ctrl, backend_handle_t backend_hd,
db_request_t request, const unsigned char *ubid);
#endif /*KBX_BACKEND_H*/

View File

@ -115,6 +115,8 @@ kbxd_set_database (ctrl_t ctrl, const char *filename_arg, int readonly)
; /* We already know it. */
else if (n > 4 && !strcmp (filename + n - 4, ".kbx"))
db_type = DB_TYPE_KBX;
else if (n > 3 && !strcmp (filename + n - 3, ".db"))
db_type = DB_TYPE_SQLITE;
else
{
log_error (_("can't use file '%s': %s\n"), filename, _("unknown suffix"));
@ -135,7 +137,11 @@ kbxd_set_database (ctrl_t ctrl, const char *filename_arg, int readonly)
case DB_TYPE_KBX:
err = be_kbx_add_resource (ctrl, &handle, filename, readonly);
break;
}
case DB_TYPE_SQLITE:
err = be_sqlite_add_resource (ctrl, &handle, filename, readonly);
break;
}
if (err)
goto leave;
@ -170,7 +176,9 @@ kbxd_release_session_info (ctrl_t ctrl)
/* Search for the keys described by (DESC,NDESC) and return them to
* the caller. If RESET is set, the search state is first reset. */
* the caller. If RESET is set, the search state is first reset.
* Only a reset guarantees that changed search description in DESC are
* considered. */
gpg_error_t
kbxd_search (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, unsigned int ndesc,
int reset)
@ -178,7 +186,6 @@ kbxd_search (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, unsigned int ndesc,
gpg_error_t err;
int i;
db_request_t request;
int start_at_ubid = 0;
if (DBG_CLOCK)
log_clock ("%s: enter", __func__);
@ -230,6 +237,11 @@ kbxd_search (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, unsigned int ndesc,
request, NULL, 0);
break;
case DB_TYPE_SQLITE:
err = be_sqlite_search (ctrl, the_database.backend_handle,
request, NULL, 0);
break;
default:
err = gpg_error (GPG_ERR_INTERNAL);
break;
@ -263,22 +275,13 @@ kbxd_search (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, unsigned int ndesc,
break;
case DB_TYPE_KBX:
if (start_at_ubid)
{
/* We need to set the startpoint for the search. */
err = be_kbx_seek (ctrl, the_database.backend_handle, request,
request->last_cached_ubid);
if (err)
{
log_debug ("%s: seeking %s to an UBID failed: %s\n", __func__,
strdbtype (the_database.db_type), gpg_strerror (err));
break;
}
}
err = be_kbx_search (ctrl, the_database.backend_handle, request,
desc, ndesc);
if (start_at_ubid && gpg_err_code (err) == GPG_ERR_EOF)
be_cache_mark_final (ctrl, request);
break;
case DB_TYPE_SQLITE:
err = be_sqlite_search (ctrl, the_database.backend_handle, request,
desc, ndesc);
break;
default:
@ -292,7 +295,6 @@ kbxd_search (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, unsigned int ndesc,
log_debug ("%s: searched %s => %s\n", __func__,
strdbtype (the_database.db_type), gpg_strerror (err));
request->any_search = 1;
start_at_ubid = 0;
if (!err)
{
request->any_found = 1;
@ -303,7 +305,6 @@ kbxd_search (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, unsigned int ndesc,
{
if (request->last_cached_final)
goto leave;
start_at_ubid = 1;
}
request->next_dbidx++;
/* FIXME: We need to see which pubkey type we need to insert. */
@ -366,6 +367,38 @@ kbxd_store (ctrl_t ctrl, const void *blob, size_t bloblen,
if (the_database.db_type == DB_TYPE_KBX)
{
err = be_kbx_seek (ctrl, the_database.backend_handle, request, ubid);
if (!err)
; /* Found - need to update. */
else if (gpg_err_code (err) == GPG_ERR_EOF)
insert = 1; /* Not found - need to insert. */
else
{
log_debug ("%s: searching fingerprint failed: %s\n",
__func__, gpg_strerror (err));
goto leave;
}
if (insert)
{
if (mode == KBXD_STORE_UPDATE)
err = gpg_error (GPG_ERR_CONFLICT);
else
err = be_kbx_insert (ctrl, the_database.backend_handle, request,
pktype, blob, bloblen);
}
else /* Update. */
{
if (mode == KBXD_STORE_INSERT)
err = gpg_error (GPG_ERR_CONFLICT);
else
err = be_kbx_update (ctrl, the_database.backend_handle, request,
pktype, blob, bloblen);
}
}
else if (the_database.db_type == DB_TYPE_SQLITE)
{
err = be_sqlite_store (ctrl, the_database.backend_handle, request,
mode, pktype, ubid, blob, bloblen);
}
else
{
@ -374,37 +407,6 @@ kbxd_store (ctrl_t ctrl, const void *blob, size_t bloblen,
err = gpg_error (GPG_ERR_INTERNAL);
}
if (!err)
; /* Found - need to update. */
else if (gpg_err_code (err) == GPG_ERR_EOF)
insert = 1; /* Not found - need to insert. */
else
{
log_debug ("%s: searching fingerprint failed: %s\n",
__func__, gpg_strerror (err));
goto leave;
}
if (insert)
{
if (mode == KBXD_STORE_UPDATE)
err = gpg_error (GPG_ERR_CONFLICT);
else if (the_database.db_type == DB_TYPE_KBX)
err = be_kbx_insert (ctrl, the_database.backend_handle, request,
pktype, blob, bloblen);
else
err = gpg_error (GPG_ERR_INTERNAL);
}
else /* Update. */
{
if (mode == KBXD_STORE_INSERT)
err = gpg_error (GPG_ERR_CONFLICT);
else if (the_database.db_type == DB_TYPE_KBX)
err = be_kbx_update (ctrl, the_database.backend_handle, request,
pktype, blob, bloblen);
else
err = gpg_error (GPG_ERR_INTERNAL);
}
leave:
release_lock (ctrl);
@ -450,6 +452,24 @@ kbxd_delete (ctrl_t ctrl, const unsigned char *ubid)
if (the_database.db_type == DB_TYPE_KBX)
{
err = be_kbx_seek (ctrl, the_database.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, the_database.backend_handle, request);
}
else if (the_database.db_type == DB_TYPE_SQLITE)
{
err = be_sqlite_delete (ctrl, the_database.backend_handle, request, ubid);
}
else
{
@ -458,24 +478,6 @@ kbxd_delete (ctrl_t ctrl, const unsigned char *ubid)
err = gpg_error (GPG_ERR_INTERNAL);
}
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;
}
if (the_database.db_type == DB_TYPE_KBX)
err = be_kbx_delete (ctrl, the_database.backend_handle, request);
else
err = gpg_error (GPG_ERR_INTERNAL);
leave:
release_lock (ctrl);

View File

@ -23,14 +23,6 @@
#include "keybox-search-desc.h"
enum kbxd_store_modes
{
KBXD_STORE_AUTO = 0, /* Update or insert. */
KBXD_STORE_INSERT, /* Allow only inserts. */
KBXD_STORE_UPDATE /* Allow only updates. */
};
gpg_error_t kbxd_set_database (ctrl_t ctrl,
const char *filename_arg, int readonly);

View File

@ -736,7 +736,8 @@ main (int argc, char **argv )
}
kbxd_init_default_ctrl (ctrl);
kbxd_set_database (ctrl, "pubring.kbx", 0);
/* kbxd_set_database (ctrl, "pubring.kbx", 0); */
kbxd_set_database (ctrl, "pubring.db", 0);
kbxd_start_command_handler (ctrl, GNUPG_INVALID_FD, 0);
kbxd_deinit_default_ctrl (ctrl);
@ -870,7 +871,8 @@ main (int argc, char **argv )
kbxd_exit (1);
}
kbxd_init_default_ctrl (ctrl);
kbxd_set_database (ctrl, "pubring.kbx", 0);
/* kbxd_set_database (ctrl, "pubring.kbx", 0); */
kbxd_set_database (ctrl, "pubring.db", 0);
kbxd_deinit_default_ctrl (ctrl);
xfree (ctrl);
}

View File

@ -137,6 +137,14 @@ struct server_control_s
#define L_(a) (a)
#endif
enum kbxd_store_modes
{
KBXD_STORE_AUTO = 0, /* Update or insert. */
KBXD_STORE_INSERT, /* Allow only inserts. */
KBXD_STORE_UPDATE /* Allow only updates. */
};
/*-- keyboxd.c --*/
void kbxd_exit (int rc) GPGRT_ATTR_NORETURN;