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:
parent
f0b33b6fb8
commit
91e61d5253
@ -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)
|
||||||
|
|
||||||
|
13
g10/gpg.c
13
g10/gpg.c
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
256
g10/keydb.c
256
g10/keydb.c
@ -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)
|
||||||
{
|
{
|
||||||
|
11
g10/keydb.h
11
g10/keydb.h
@ -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);
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user