1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

gpg: First patches to support a keybox storage backend.

* kbx/keybox-defs.h (_keybox_write_header_blob): Move prototype to ..
* kbx/keybox.h: here.
* kbx/keybox-init.c (keybox_lock): Add dummy function
* g10/keydb.c: Include keybox.h.
(KeydbResourceType): Add KEYDB_RESOURCE_TYPE_KEYBOX.
(struct resource_item): Add field kb.
(maybe_create_keyring_or_box): Add error descriptions to diagnostics.
Add arg IS_BOX.  Write a header for a new keybox file.
(keydb_add_resource): No more need for the force flag.  Rename the
local variable "force" to "create".  Add URL scheme "gnupg-kbx".  Add
magic test to detect a keybox file.  Add basic support for keybox.
(keydb_new, keydb_get_resource_name, keydb_delete_keyblock)
(keydb_locate_writable, keydb_search_reset, keydb_search2): Add
support for keybox.
(lock_all, unlock_all): Ditto.
* g10/Makefile.am (needed_libs): Add libkeybox.a.
(gpg2_LDADD, gpgv2_LDADD): Add KSBA_LIBS as a workaround.

* g10/keydb.h (KEYDB_RESOURCE_FLAG_PRIMARY)
KEYDB_RESOURCE_FLAG_DEFAULT, KEYDB_RESOURCE_FLAG_READONLY): New.
* g10/gpg.c, g10/gpgv.c (main): Use new constants.
--

I did most of these changes back in 2011 and only cleaned them up
now.  More to follow soon.
This commit is contained in:
Werner Koch 2012-12-27 15:04:29 +01:00
parent f0b33b6fb8
commit 91e61d5253
8 changed files with 243 additions and 80 deletions

View File

@ -27,7 +27,7 @@ include $(top_srcdir)/am/cmacros.am
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS) AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
needed_libs = $(libcommon) ../gl/libgnu.a needed_libs = ../kbx/libkeybox.a $(libcommon) ../gl/libgnu.a
bin_PROGRAMS = gpg2 bin_PROGRAMS = gpg2
if !HAVE_W32CE_SYSTEM if !HAVE_W32CE_SYSTEM
@ -120,13 +120,18 @@ gpgv2_SOURCES = gpgv.c \
# ks-db.h \ # ks-db.h \
# $(common_source) # $(common_source)
# FIXME: Libkeybox.a links to libksba thus we need to add libksba
# here, even that it is not used by gpg. A proper solution would
# either to split up libkeybox.a or to use a separate keybox daemon.
LDADD = $(needed_libs) ../common/libgpgrl.a \ LDADD = $(needed_libs) ../common/libgpgrl.a \
$(ZLIBS) $(DNSLIBS) $(LIBREADLINE) \ $(ZLIBS) $(DNSLIBS) $(LIBREADLINE) \
$(LIBINTL) $(CAPLIBS) $(NETLIBS) $(LIBINTL) $(CAPLIBS) $(NETLIBS)
gpg2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ gpg2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) \
$(KSBA_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
$(LIBICONV) $(extra_sys_libs) $(LIBICONV) $(extra_sys_libs)
gpg2_LDFLAGS = $(extra_bin_ldflags) gpg2_LDFLAGS = $(extra_bin_ldflags)
gpgv2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ gpgv2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) \
$(KSBA_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
$(LIBICONV) $(extra_sys_libs) $(LIBICONV) $(extra_sys_libs)
gpgv2_LDFLAGS = $(extra_bin_ldflags) gpgv2_LDFLAGS = $(extra_bin_ldflags)

View File

@ -2249,8 +2249,8 @@ main (int argc, char **argv)
case oAnswerNo: opt.answer_no = 1; break; case oAnswerNo: opt.answer_no = 1; break;
case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
case oPrimaryKeyring: case oPrimaryKeyring:
sl=append_to_strlist( &nrings, pargs.r.ret_str); sl = append_to_strlist (&nrings, pargs.r.ret_str);
sl->flags=2; sl->flags = KEYDB_RESOURCE_FLAG_PRIMARY;
break; break;
case oShowKeyring: case oShowKeyring:
deprecated_warning(configname,configlineno,"--show-keyring", deprecated_warning(configname,configlineno,"--show-keyring",
@ -3398,11 +3398,7 @@ main (int argc, char **argv)
if( opt.verbose > 1 ) if( opt.verbose > 1 )
set_packet_list_mode(1); set_packet_list_mode(1);
/* Add the keyrings, but not for some special commands. Also /* Add the keyrings, but not for some special commands.
avoid adding the secret keyring for a couple of commands to
avoid unneeded access in case the secrings are stored on a
floppy.
We always need to add the keyrings if we are running under We always need to add the keyrings if we are running under
SELinux, this is so that the rings are added to the list of SELinux, this is so that the rings are added to the list of
secured files. */ secured files. */
@ -3410,7 +3406,8 @@ main (int argc, char **argv)
|| (cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfTest) ) || (cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfTest) )
{ {
if (!nrings || default_keyring) /* Add default ring. */ if (!nrings || default_keyring) /* Add default ring. */
keydb_add_resource ("pubring" EXTSEP_S "gpg", 4); keydb_add_resource ("pubring" EXTSEP_S "gpg",
KEYDB_RESOURCE_FLAG_DEFAULT);
for (sl = nrings; sl; sl = sl->next ) for (sl = nrings; sl; sl = sl->next )
keydb_add_resource (sl->d, sl->flags); keydb_add_resource (sl->d, sl->flags);
} }

View File

@ -196,11 +196,12 @@ main( int argc, char **argv )
if (opt.verbose > 1) if (opt.verbose > 1)
set_packet_list_mode(1); set_packet_list_mode(1);
/* Note: We open all keyrings in read-only mode (flag value: 8). */ /* Note: We open all keyrings in read-only mode. */
if (!nrings) /* No keyring given: use default one. */ if (!nrings) /* No keyring given: use default one. */
keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 8); keydb_add_resource ("trustedkeys" EXTSEP_S "gpg",
KEYDB_RESOURCE_FLAG_READONLY);
for (sl = nrings; sl; sl = sl->next) for (sl = nrings; sl; sl = sl->next)
keydb_add_resource (sl->d, 8); keydb_add_resource (sl->d, KEYDB_RESOURCE_FLAG_READONLY);
FREE_STRLIST (nrings); FREE_STRLIST (nrings);

View File

@ -34,6 +34,7 @@
#include "main.h" /*try_make_homedir ()*/ #include "main.h" /*try_make_homedir ()*/
#include "packet.h" #include "packet.h"
#include "keyring.h" #include "keyring.h"
#include "../kbx/keybox.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"
@ -42,7 +43,8 @@ static int active_handles;
typedef enum typedef enum
{ {
KEYDB_RESOURCE_TYPE_NONE = 0, KEYDB_RESOURCE_TYPE_NONE = 0,
KEYDB_RESOURCE_TYPE_KEYRING KEYDB_RESOURCE_TYPE_KEYRING,
KEYDB_RESOURCE_TYPE_KEYBOX
} KeydbResourceType; } KeydbResourceType;
#define MAX_KEYDB_RESOURCES 40 #define MAX_KEYDB_RESOURCES 40
@ -51,6 +53,7 @@ struct resource_item
KeydbResourceType type; KeydbResourceType type;
union { union {
KEYRING_HANDLE kr; KEYRING_HANDLE kr;
KEYBOX_HANDLE kb;
} u; } u;
void *token; void *token;
}; };
@ -73,12 +76,12 @@ static int lock_all (KEYDB_HANDLE hd);
static void unlock_all (KEYDB_HANDLE hd); static void unlock_all (KEYDB_HANDLE hd);
/* Handle the creation of a keyring if it does not yet exist. Take /* Handle the creation of a keyring or a keybox if it does not yet
into acount that other processes might have the keyring already exist. Take into acount that other processes might have the
locked. This lock check does not work if the directory itself is keyring/keybox already locked. This lock check does not work if
not yet available. */ the directory itself is not yet available. */
static int static int
maybe_create_keyring (char *filename, int force) maybe_create_keyring_or_box (char *filename, int is_box, int force)
{ {
dotlock_t lockhd = NULL; dotlock_t lockhd = NULL;
IOBUF iobuf; IOBUF iobuf;
@ -139,29 +142,31 @@ maybe_create_keyring (char *filename, int force)
lockhd = dotlock_create (filename, 0); lockhd = dotlock_create (filename, 0);
if (!lockhd) if (!lockhd)
{ {
rc = gpg_error_from_syserror ();
/* A reason for this to fail is that the directory is not /* A reason for this to fail is that the directory is not
writable. However, this whole locking stuff does not make writable. However, this whole locking stuff does not make
sense if this is the case. An empty non-writable directory sense if this is the case. An empty non-writable directory
with no keyring is not really useful at all. */ with no keyring is not really useful at all. */
if (opt.verbose) if (opt.verbose)
log_info ("can't allocate lock for '%s'\n", filename ); log_info ("can't allocate lock for '%s': %s\n",
filename, gpg_strerror (rc));
if (!force) if (!force)
return gpg_error (GPG_ERR_ENOENT); return gpg_error (GPG_ERR_ENOENT);
else else
return gpg_error (GPG_ERR_GENERAL); return rc;
} }
if ( dotlock_take (lockhd, -1) ) if ( dotlock_take (lockhd, -1) )
{ {
rc = gpg_error_from_syserror ();
/* This is something bad. Probably a stale lockfile. */ /* This is something bad. Probably a stale lockfile. */
log_info ("can't lock '%s'\n", filename ); log_info ("can't lock '%s': %s\n", filename, gpg_strerror (rc));
rc = G10ERR_GENERAL;
goto leave; goto leave;
} }
/* Now the real test while we are locked. */ /* Now the real test while we are locked. */
if (!access(filename, F_OK)) if (!access (filename, F_OK))
{ {
rc = 0; /* Okay, we may access the file now. */ rc = 0; /* Okay, we may access the file now. */
goto leave; goto leave;
@ -180,17 +185,51 @@ maybe_create_keyring (char *filename, int force)
if (!iobuf) if (!iobuf)
{ {
rc = gpg_error_from_syserror (); rc = gpg_error_from_syserror ();
log_error ( _("error creating keyring '%s': %s\n"), if (is_box)
filename, strerror(errno)); log_error (_("error creating keybox '%s': %s\n"),
filename, gpg_strerror (rc));
else
log_error (_("error creating keyring '%s': %s\n"),
filename, gpg_strerror (rc));
goto leave; goto leave;
} }
if (!opt.quiet)
log_info (_("keyring '%s' created\n"), filename);
iobuf_close (iobuf); iobuf_close (iobuf);
/* Must invalidate that ugly cache */ /* Must invalidate that ugly cache */
iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, filename); iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, filename);
/* Make sure that at least one record is in a new keybox file, so
that the detection magic will work the next time it is used. */
if (is_box)
{
FILE *fp = fopen (filename, "w");
if (!fp)
rc = gpg_error_from_syserror ();
else
{
rc = _keybox_write_header_blob (fp);
fclose (fp);
}
if (rc)
{
if (is_box)
log_error (_("error creating keybox '%s': %s\n"),
filename, gpg_strerror (rc));
else
log_error (_("error creating keyring '%s': %s\n"),
filename, gpg_strerror (rc));
goto leave;
}
}
if (!opt.quiet)
{
if (is_box)
log_info (_("keybox '%s' created\n"), filename);
else
log_info (_("keyring '%s' created\n"), filename);
}
rc = 0; rc = 0;
leave: leave:
@ -204,51 +243,49 @@ maybe_create_keyring (char *filename, int force)
/* /*
* Register a resource (which currently may only be a keyring file). * Register a resource (keyring or aeybox). The first keyring or
* The first keyring which is added by this function is * keybox which is added by this function is created if it does not
* created if it does not exist. * exist. FLAGS are a combination of the KEYDB_RESOURCE_FLAG_
* Note: this function may be called before secure memory is * constants as defined in keydb.h.
* available.
* Flag 1 - Force.
* Flag 2 - Mark resource as primary.
* Flag 4 - This is a default resources.
* Flag 8 - Open as read-only.
*/ */
gpg_error_t gpg_error_t
keydb_add_resource (const char *url, int flags) keydb_add_resource (const char *url, unsigned int flags)
{ {
static int any_public; static int any_registered;
const char *resname = url; const char *resname = url;
char *filename = NULL; char *filename = NULL;
int force = (flags&1); int create;
int read_only = !!(flags&8); int read_only = !!(flags&KEYDB_RESOURCE_FLAG_READONLY);
int rc = 0; int rc = 0;
KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
void *token; void *token;
if (read_only) /* Create the resource if it is the first registered one. */
force = 0; create = (!read_only && !any_registered);
/* Do we have an URL? /* Do we have an URL?
* gnupg-ring:filename := this is a plain keyring * gnupg-ring:filename := this is a plain keyring.
* gnupg-kbx:filename := this is a keybox file.
* filename := See what is is, but create as plain keyring. * filename := See what is is, but create as plain keyring.
*/ */
if (strlen (resname) > 11) if (strlen (resname) > 11 && !strncmp( resname, "gnupg-ring:", 11) )
{ {
if (!strncmp( resname, "gnupg-ring:", 11) ) rt = KEYDB_RESOURCE_TYPE_KEYRING;
{ resname += 11;
rt = KEYDB_RESOURCE_TYPE_KEYRING;
resname += 11;
}
#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
else if (strchr (resname, ':'))
{
log_error ("invalid key resource URL '%s'\n", url );
rc = gpg_error (GPG_ERR_GENERAL);
goto leave;
}
#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
} }
else if (strlen (resname) > 10 && !strncmp (resname, "gnupg-kbx:", 10) )
{
rt = KEYDB_RESOURCE_TYPE_KEYBOX;
resname += 10;
}
#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
else if (strchr (resname, ':'))
{
log_error ("invalid key resource URL '%s'\n", url );
rc = gpg_error (GPG_ERR_GENERAL);
goto leave;
}
#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
if (*resname != DIRSEP_C ) if (*resname != DIRSEP_C )
{ {
@ -261,9 +298,6 @@ keydb_add_resource (const char *url, int flags)
else else
filename = xstrdup (resname); filename = xstrdup (resname);
if (!force && !read_only)
force = !any_public;
/* See whether we can determine the filetype. */ /* See whether we can determine the filetype. */
if (rt == KEYDB_RESOURCE_TYPE_NONE) if (rt == KEYDB_RESOURCE_TYPE_NONE)
{ {
@ -273,20 +307,25 @@ keydb_add_resource (const char *url, int flags)
{ {
u32 magic; u32 magic;
if (fread( &magic, 4, 1, fp) == 1 ) if (fread (&magic, 4, 1, fp) == 1 )
{ {
if (magic == 0x13579ace || magic == 0xce9a5713) if (magic == 0x13579ace || magic == 0xce9a5713)
; /* GDBM magic - not anymore supported. */ ; /* GDBM magic - not anymore supported. */
else if (fread (&magic, 4, 1, fp) == 1
&& !memcmp (&magic, "\x01", 1)
&& fread (&magic, 4, 1, fp) == 1
&& !memcmp (&magic, "KBXf", 4))
rt = KEYDB_RESOURCE_TYPE_KEYBOX;
else else
rt = KEYDB_RESOURCE_TYPE_KEYRING; rt = KEYDB_RESOURCE_TYPE_KEYRING;
} }
else /* Maybe empty: assume keyring. */ else /* Maybe empty: assume keyring. */
rt = KEYDB_RESOURCE_TYPE_KEYRING; rt = KEYDB_RESOURCE_TYPE_KEYRING;
fclose( fp ); fclose (fp);
} }
else /* No file yet: create keyring. */ else /* No file yet: create keybox. */
rt = KEYDB_RESOURCE_TYPE_KEYRING; rt = KEYDB_RESOURCE_TYPE_KEYBOX;
} }
switch (rt) switch (rt)
@ -297,7 +336,7 @@ keydb_add_resource (const char *url, int flags)
goto leave; goto leave;
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
rc = maybe_create_keyring (filename, force); rc = maybe_create_keyring_or_box (filename, create, 0);
if (rc) if (rc)
goto leave; goto leave;
@ -307,7 +346,7 @@ keydb_add_resource (const char *url, int flags)
rc = gpg_error (GPG_ERR_RESOURCE_LIMIT); rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
else else
{ {
if (flags&2) if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY))
primary_keyring = token; primary_keyring = token;
all_resources[used_resources].type = rt; all_resources[used_resources].type = rt;
all_resources[used_resources].u.kr = NULL; /* Not used here */ all_resources[used_resources].u.kr = NULL; /* Not used here */
@ -320,24 +359,61 @@ keydb_add_resource (const char *url, int flags)
/* This keyring was already registered, so ignore it. /* This keyring was already registered, so ignore it.
However, we can still mark it as primary even if it was However, we can still mark it as primary even if it was
already registered. */ already registered. */
if (flags&2) if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY))
primary_keyring = token; primary_keyring = token;
} }
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
{
rc = maybe_create_keyring_or_box (filename, create, 1);
if (rc)
goto leave;
/* FIXME: How do we register a read-only keybox? */
token = keybox_register_file (filename, 0);
if (token)
{
if (used_resources >= MAX_KEYDB_RESOURCES)
rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
else
{
/* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */
/* primary_keyring = token; */
all_resources[used_resources].type = rt;
all_resources[used_resources].u.kb = NULL; /* Not used here */
all_resources[used_resources].token = token;
/* FIXME: Do a compress run if needed and no other
user is currently using the keybox. */
used_resources++;
}
}
else
{
/* Already registered. We will mark it as the primary key
if requested. */
/* FIXME: How to do that? Change the keybox interface? */
/* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */
/* primary_keyring = token; */
}
}
break;
default: default:
log_error ("resource type of '%s' not supported\n", url); log_error ("resource type of '%s' not supported\n", url);
rc = gpg_error (GPG_ERR_GENERAL); rc = gpg_error (GPG_ERR_GENERAL);
goto leave; goto leave;
} }
/* fixme: check directory permissions and print a warning */ /* fixme: check directory permissions and print a warning */
leave: leave:
if (rc) if (rc)
log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (rc)); log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (rc));
else else
any_public = 1; any_registered = 1;
xfree (filename); xfree (filename);
return rc; return rc;
} }
@ -371,6 +447,17 @@ keydb_new (void)
} }
j++; j++;
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
hd->active[j].type = all_resources[i].type;
hd->active[j].token = all_resources[i].token;
hd->active[j].u.kb = keybox_new (all_resources[i].token, 0);
if (!hd->active[j].u.kb)
{
xfree (hd);
return NULL; /* fixme: release all previously allocated handles*/
}
j++;
break;
} }
} }
hd->used = j; hd->used = j;
@ -399,6 +486,9 @@ keydb_release (KEYDB_HANDLE hd)
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
keyring_release (hd->active[i].u.kr); keyring_release (hd->active[i].u.kr);
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
keybox_release (hd->active[i].u.kb);
break;
} }
} }
@ -438,6 +528,9 @@ keydb_get_resource_name (KEYDB_HANDLE hd)
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
s = keyring_get_resource_name (hd->active[idx].u.kr); s = keyring_get_resource_name (hd->active[idx].u.kr);
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
s = keybox_get_resource_name (hd->active[idx].u.kb);
break;
} }
return s? s: ""; return s? s: "";
@ -450,6 +543,13 @@ lock_all (KEYDB_HANDLE hd)
{ {
int i, rc = 0; int i, rc = 0;
/* Fixme: This locking scheme may lead to a deadlock if the resources
are not added in the same order by all processes. We are
currently only allowing one resource so it is not a problem.
[Oops: Who claimed the latter]
To fix this we need to use a lock file to protect lock_all. */
for (i=0; !rc && i < hd->used; i++) for (i=0; !rc && i < hd->used; i++)
{ {
switch (hd->active[i].type) switch (hd->active[i].type)
@ -459,12 +559,15 @@ lock_all (KEYDB_HANDLE hd)
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
rc = keyring_lock (hd->active[i].u.kr, 1); rc = keyring_lock (hd->active[i].u.kr, 1);
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
rc = keybox_lock (hd->active[i].u.kb, 1);
break;
} }
} }
if (rc) if (rc)
{ {
/* Revert the already set locks. */ /* Revert the already taken locks. */
for (i--; i >= 0; i--) for (i--; i >= 0; i--)
{ {
switch (hd->active[i].type) switch (hd->active[i].type)
@ -474,6 +577,9 @@ lock_all (KEYDB_HANDLE hd)
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
keyring_lock (hd->active[i].u.kr, 0); keyring_lock (hd->active[i].u.kr, 0);
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
rc = keybox_lock (hd->active[i].u.kb, 0);
break;
} }
} }
} }
@ -501,6 +607,9 @@ unlock_all (KEYDB_HANDLE hd)
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
keyring_lock (hd->active[i].u.kr, 0); keyring_lock (hd->active[i].u.kr, 0);
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
keybox_lock (hd->active[i].u.kb, 0);
break;
} }
} }
hd->locked = 0; hd->locked = 0;
@ -532,6 +641,11 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
err = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb); err = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
break; break;
/* case KEYDB_RESOURCE_TYPE_KEYBOX: */
/* err = keybox_get_keyblock (hd->active[hd->found].u.kb, ret_kb); */
/* if (!err) */
/* err = parse_keyblock (image, imagelen) */
/* break; */
} }
return err; return err;
@ -566,6 +680,12 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb); rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
break; break;
/* case KEYDB_RESOURCE_TYPE_KEYRING: */
/* rc = build_keyblock (kb, &image, &imagelen); */
/* if (!rc) */
/* rc = keybox_update_keyblock (hd->active[hd->found].u.kb, */
/* image, imagelen); */
/* break; */
} }
unlock_all (hd); unlock_all (hd);
@ -607,6 +727,11 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb); rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
break; break;
/* case KEYDB_RESOURCE_TYPE_KEYBOX: */
/* rc = build_keyblock (kb, &image, &imagelen); */
/* if (!rc) */
/* rc = keybox_insert_keyblock (hd->active[idx].u.kb, image, imagelen); */
/* break; */
} }
unlock_all (hd); unlock_all (hd);
@ -643,6 +768,9 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
rc = keyring_delete_keyblock (hd->active[hd->found].u.kr); rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
rc = keybox_delete (hd->active[hd->found].u.kb);
break;
} }
unlock_all (hd); unlock_all (hd);
@ -700,6 +828,10 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
if (keyring_is_writable (hd->active[hd->current].token)) if (keyring_is_writable (hd->active[hd->current].token))
return 0; /* found (hd->current is set to it) */ return 0; /* found (hd->current is set to it) */
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
if (keybox_is_writable (hd->active[hd->current].token))
return 0; /* found (hd->current is set to it) */
break;
} }
} }
@ -758,6 +890,9 @@ keydb_search_reset (KEYDB_HANDLE hd)
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
rc = keyring_search_reset (hd->active[i].u.kr); rc = keyring_search_reset (hd->active[i].u.kr);
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
rc = keybox_search_reset (hd->active[i].u.kb);
break;
} }
} }
return rc; return rc;
@ -792,6 +927,9 @@ keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
rc = keyring_search (hd->active[hd->current].u.kr, desc, rc = keyring_search (hd->active[hd->current].u.kr, desc,
ndesc, descindex); ndesc, descindex);
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
rc = keybox_search (hd->active[hd->current].u.kb, desc, ndesc);
break;
} }
if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
{ {

View File

@ -128,11 +128,12 @@ union pref_hint
/*-- keydb.c --*/ /*-- keydb.c --*/
/* #define KEYDB_RESOURCE_FLAG_PRIMARY 2 /* The primary resource. */
Flag 1 == force #define KEYDB_RESOURCE_FLAG_DEFAULT 4 /* The default one. */
Flag 2 == default #define KEYDB_RESOURCE_FLAG_READONLY 8 /* Open in read only mode. */
*/
gpg_error_t keydb_add_resource (const char *url, int flags); gpg_error_t keydb_add_resource (const char *url, unsigned int flags);
KEYDB_HANDLE keydb_new (void); KEYDB_HANDLE keydb_new (void);
void keydb_release (KEYDB_HANDLE hd); void keydb_release (KEYDB_HANDLE hd);
const char *keydb_get_resource_name (KEYDB_HANDLE hd); const char *keydb_get_resource_name (KEYDB_HANDLE hd);

View File

@ -182,7 +182,6 @@ void _keybox_destroy_openpgp_info (keybox_openpgp_info_t info);
int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp); int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp);
int _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted); int _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted);
int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp); int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp);
int _keybox_write_header_blob (FILE *fp);
/*-- keybox-search.c --*/ /*-- keybox-search.c --*/
gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer, gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer,

View File

@ -200,3 +200,20 @@ _keybox_close_file (KEYBOX_HANDLE hd)
} }
assert (!hd->fp); assert (!hd->fp);
} }
/*
* Lock the keybox at handle HD, or unlock if YES is false. Note that
* we currently ignore the handle and lock all registered keyboxes.
*/
int
keybox_lock (KEYBOX_HANDLE hd, int yes)
{
/* FIXME: We need to implement it before we can use it with gpg.
gpgsm does the locking in its local keydb.c driver; this should
be changed as well. */
(void)hd;
(void)yes;
return 0;
}

View File

@ -71,6 +71,12 @@ void keybox_release (KEYBOX_HANDLE hd);
const char *keybox_get_resource_name (KEYBOX_HANDLE hd); const char *keybox_get_resource_name (KEYBOX_HANDLE hd);
int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes); int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes);
int keybox_lock (KEYBOX_HANDLE hd, int yes);
/*-- keybox-file.c --*/
/* Fixme: This function does not belong here: Provide a better
interface to create a new keybox file. */
int _keybox_write_header_blob (FILE *fp);
/*-- keybox-search.c --*/ /*-- keybox-search.c --*/
#ifdef KEYBOX_WITH_X509 #ifdef KEYBOX_WITH_X509
@ -98,7 +104,6 @@ int keybox_compress (KEYBOX_HANDLE hd);
/*-- --*/ /*-- --*/
#if 0 #if 0
int keybox_lock (KEYBOX_HANDLE hd, int yes);
int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb); int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb);
int keybox_locate_writable (KEYBOX_HANDLE hd); int keybox_locate_writable (KEYBOX_HANDLE hd);
int keybox_search_reset (KEYBOX_HANDLE hd); int keybox_search_reset (KEYBOX_HANDLE hd);