summaryrefslogtreecommitdiffstats
path: root/kbx
diff options
context:
space:
mode:
Diffstat (limited to 'kbx')
-rw-r--r--kbx/Makefile.in21
-rw-r--r--kbx/keybox-defs.h8
-rw-r--r--kbx/keybox-dump.c4
-rw-r--r--kbx/keybox-init.c126
-rw-r--r--kbx/keybox-search.c30
-rw-r--r--kbx/keybox-update.c129
-rw-r--r--kbx/keybox.h1
7 files changed, 218 insertions, 101 deletions
diff --git a/kbx/Makefile.in b/kbx/Makefile.in
index c3a58cb..483d677 100644
--- a/kbx/Makefile.in
+++ b/kbx/Makefile.in
@@ -148,17 +148,16 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \
$(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/iconv.m4 \
- $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/ksba.m4 \
- $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/ldap.m4 \
- $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
- $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libassuan.m4 \
- $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/nls.m4 \
- $(top_srcdir)/m4/npth.m4 $(top_srcdir)/m4/ntbtls.m4 \
- $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \
- $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/readline.m4 \
- $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
- $(top_srcdir)/m4/tar-ustar.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/ksba.m4 $(top_srcdir)/m4/lcmessage.m4 \
+ $(top_srcdir)/m4/ldap.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libassuan.m4 $(top_srcdir)/m4/libgcrypt.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/npth.m4 \
+ $(top_srcdir)/m4/ntbtls.m4 $(top_srcdir)/m4/pkg.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/socklen.m4 \
+ $(top_srcdir)/m4/sys_socket_h.m4 $(top_srcdir)/m4/tar-ustar.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h
index 2751b4b..eafcf2c 100644
--- a/kbx/keybox-defs.h
+++ b/kbx/keybox-defs.h
@@ -139,6 +139,14 @@ typedef struct _keybox_openpgp_info *keybox_openpgp_info_t;
/* } keybox_opt; */
/*-- keybox-init.c --*/
+
+#define KEYBOX_LL_OPEN_READ 0
+#define KEYBOX_LL_OPEN_UPDATE 1
+#define KEYBOX_LL_OPEN_CREATE 2
+gpg_error_t _keybox_ll_open (estream_t *rfp, const char *fname,
+ unsigned int mode);
+gpg_error_t _keybox_ll_close (estream_t fp);
+
void _keybox_close_file (KEYBOX_HANDLE hd);
diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c
index 3e66b72..3bf63c9 100644
--- a/kbx/keybox-dump.c
+++ b/kbx/keybox-dump.c
@@ -810,6 +810,8 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp)
gpg_error_t tmperr = gpg_error_from_syserror ();
fprintf (outfp, "error allocating array for '%s': %s\n",
filename, strerror(errno));
+ if (fp != es_stdin)
+ es_fclose (fp);
return tmperr;
}
dupitems_count = 0;
@@ -834,6 +836,8 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp)
fprintf (outfp, "error reallocating array for '%s': %s\n",
filename, strerror(errno));
free (dupitems);
+ if (fp != es_stdin)
+ es_fclose (fp);
return tmperr;
}
dupitems = tmp;
diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c
index f07ba8d..1318e3e 100644
--- a/kbx/keybox-init.c
+++ b/kbx/keybox-init.c
@@ -28,8 +28,26 @@
#include "../common/sysutils.h"
#include "../common/mischelp.h"
+#ifdef HAVE_W32_SYSTEM
+# define DEFAULT_LL_BUFFER_SIZE 128
+#else
+# define DEFAULT_LL_BUFFER_SIZE 64
+#endif
+
+static unsigned int ll_buffer_size = DEFAULT_LL_BUFFER_SIZE;
+
static KB_NAME kb_names;
+/* This object is used to mahe setvbuf buffers. We use a short arary
+ * to be able to reuse already allocated buffers. */
+struct stream_buffer_s
+{
+ int inuse; /* True if used by a stream. */
+ size_t bufsize;
+ char *buf;
+};
+static struct stream_buffer_s stream_buffers[5];
+
/* Register a filename for plain keybox files. Returns 0 on success,
* GPG_ERR_EEXIST if it has already been registered, or another error
@@ -85,6 +103,16 @@ keybox_is_writable (void *token)
}
+/* Change the default buffering to KBYTES KiB; using 0 uses the syste
+ * buffers. This function must be called early. */
+void
+keybox_set_buffersize (unsigned int kbytes, int reserved)
+{
+ (void)reserved;
+ /* Round down to 8k multiples. */
+ ll_buffer_size = (kbytes + 7)/8 * 8;
+}
+
static KEYBOX_HANDLE
do_keybox_new (KB_NAME resource, int secret, int for_openpgp)
@@ -180,7 +208,7 @@ keybox_release (KEYBOX_HANDLE hd)
_keybox_release_blob (hd->saved_found.blob);
if (hd->fp)
{
- es_fclose (hd->fp);
+ _keybox_ll_close (hd->fp);
hd->fp = NULL;
}
xfree (hd->word_match.name);
@@ -236,6 +264,100 @@ keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes)
}
+/* Low-level open function to be used for keybox files. This function
+ * also manages custom buffering. On success 0 is returned and a new
+ * file pointer stored at RFP; on error an error code is returned and
+ * NULL is stored at RFP. MODE is one of
+ * KEYBOX_LL_OPEN_READ(0) := fopen mode is "rb"
+ * KEYBOX_LL_OPEN_UPDATE := fopen mode is "r+b"
+ * KEYBOX_LL_OPEN_CREATE := fopen mode is "wb"
+ */
+gpg_error_t
+_keybox_ll_open (estream_t *rfp, const char *fname, unsigned int mode)
+{
+ estream_t fp;
+ int i;
+ size_t bufsize;
+
+ *rfp = NULL;
+
+ fp = es_fopen (fname,
+ mode == KEYBOX_LL_OPEN_CREATE
+ ? "wb,sysopen,sequential" :
+ mode == KEYBOX_LL_OPEN_UPDATE
+ ? "r+b,sysopen,sequential" :
+ "rb,sysopen,sequential");
+ if (!fp)
+ return gpg_error_from_syserror ();
+
+ if (ll_buffer_size)
+ {
+ for (i=0; i < DIM (stream_buffers); i++)
+ if (!stream_buffers[i].inuse)
+ {
+ /* There is a free slot - we can use a larger buffer. */
+ stream_buffers[i].inuse = 1;
+ if (!stream_buffers[i].buf)
+ {
+ bufsize = ll_buffer_size * 1024;
+ stream_buffers[i].buf = xtrymalloc (bufsize);
+ if (stream_buffers[i].buf)
+ stream_buffers[i].bufsize = bufsize;
+ else
+ {
+ log_info ("can't allocate a large buffer for a kbx file;"
+ " using default\n");
+ stream_buffers[i].inuse = 0;
+ }
+ }
+
+ if (stream_buffers[i].buf)
+ {
+ es_setvbuf (fp, stream_buffers[i].buf, _IOFBF,
+ stream_buffers[i].bufsize);
+ es_opaque_set (fp, stream_buffers + i);
+ }
+ break;
+ }
+ }
+
+ *rfp = fp;
+ return 0;
+}
+
+
+/* Wrapper around es_fclose to be used for file opened with
+ * _keybox_ll_open. */
+gpg_error_t
+_keybox_ll_close (estream_t fp)
+{
+ gpg_error_t err;
+ struct stream_buffer_s *sbuf;
+ int i;
+
+ if (!fp)
+ return 0;
+
+ sbuf = ll_buffer_size? es_opaque_get (fp) : NULL;
+ if (es_fclose (fp))
+ err = gpg_error_from_syserror ();
+ else
+ err = 0;
+ if (sbuf)
+ {
+ for (i=0; i < DIM (stream_buffers); i++)
+ if (stream_buffers + i == sbuf)
+ break;
+ log_assert (i < DIM (stream_buffers));
+ stream_buffers[i].inuse = 0;
+ }
+
+
+ return err;
+}
+
+
+
/* Close the file of the resource identified by HD. For consistent
results this function closes the files of all handles pointing to
the resource identified by HD. */
@@ -253,7 +375,7 @@ _keybox_close_file (KEYBOX_HANDLE hd)
{
if (roverhd->fp)
{
- es_fclose (roverhd->fp);
+ _keybox_ll_close (roverhd->fp);
roverhd->fp = NULL;
}
}
diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c
index 263a166..b1aee9e 100644
--- a/kbx/keybox-search.c
+++ b/kbx/keybox-search.c
@@ -777,28 +777,12 @@ release_sn_array (struct sn_array_s *array, size_t size)
}
-/* Helper to open the file. */
-static gpg_error_t
-open_file (KEYBOX_HANDLE hd)
-{
-
- hd->fp = es_fopen (hd->kb->fname, "rb");
- if (!hd->fp)
- {
- hd->error = gpg_error_from_syserror ();
- return hd->error;
- }
-
- return 0;
-}
-
-
/*
-
- The search API
-
-*/
+ *
+ * The search API
+ *
+ */
gpg_error_t
keybox_search_reset (KEYBOX_HANDLE hd)
@@ -822,7 +806,7 @@ keybox_search_reset (KEYBOX_HANDLE hd)
{
/* Ooops. Seek did not work. Close so that the search will
* open the file again. */
- es_fclose (hd->fp);
+ _keybox_ll_close (hd->fp);
hd->fp = NULL;
}
#endif
@@ -901,7 +885,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc,
if (!hd->fp)
{
- rc = open_file (hd);
+ rc = _keybox_ll_open (&hd->fp, hd->kb->fname, 0);
if (rc)
{
xfree (sn_array);
@@ -1310,7 +1294,7 @@ keybox_seek (KEYBOX_HANDLE hd, off_t offset)
return 0;
}
- err = open_file (hd);
+ err = _keybox_ll_open (&hd->fp, hd->kb->fname, 0);
if (err)
return err;
}
diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c
index 6e45f3d..15b5dbf 100644
--- a/kbx/keybox-update.c
+++ b/kbx/keybox-update.c
@@ -78,10 +78,9 @@ create_tmp_file (const char *template,
err = keybox_tmp_names (template, 0, r_bakfname, r_tmpfname);
if (!err)
{
- *r_fp = es_fopen (*r_tmpfname, "wb");
- if (!*r_fp)
+ err = _keybox_ll_open (r_fp, *r_tmpfname, KEYBOX_LL_OPEN_CREATE);
+ if (err)
{
- err = gpg_error_from_syserror ();
xfree (*r_tmpfname);
*r_tmpfname = NULL;
xfree (*r_bakfname);
@@ -174,31 +173,32 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
if ((ec = gnupg_access (fname, W_OK)))
return gpg_error (ec);
- fp = es_fopen (fname, "rb");
- if (mode == FILECOPY_INSERT && !fp && errno == ENOENT)
+ rc = _keybox_ll_open (&fp, fname, 0);
+ if (mode == FILECOPY_INSERT && gpg_err_code (rc) == GPG_ERR_ENOENT)
{
/* Insert mode but file does not exist:
- Create a new keybox file. */
- newfp = es_fopen (fname, "wb");
- if (!newfp )
- return gpg_error_from_syserror ();
+ * Create a new keybox file. */
+ rc = _keybox_ll_open (&newfp, fname, KEYBOX_LL_OPEN_CREATE);
+ if (rc)
+ return rc;
rc = _keybox_write_header_blob (newfp, for_openpgp);
if (rc)
{
- es_fclose (newfp);
+ _keybox_ll_close (newfp);
return rc;
}
rc = _keybox_write_blob (blob, newfp, NULL);
if (rc)
{
- es_fclose (newfp);
+ _keybox_ll_close (newfp);
return rc;
}
- if ( es_fclose (newfp) )
- return gpg_error_from_syserror ();
+ rc = _keybox_ll_close (newfp);
+ if (rc)
+ return rc;
/* if (chmod( fname, S_IRUSR | S_IWUSR )) */
/* { */
@@ -218,7 +218,7 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
if (rc)
{
- es_fclose (fp);
+ _keybox_ll_close (fp);
goto leave;
}
@@ -242,16 +242,16 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
if (es_fwrite (buffer, nread, 1, newfp) != 1)
{
rc = gpg_error_from_syserror ();
- es_fclose (fp);
- es_fclose (newfp);
+ _keybox_ll_close (fp);
+ _keybox_ll_close (newfp);
goto leave;
}
}
if (es_ferror (fp))
{
rc = gpg_error_from_syserror ();
- es_fclose (fp);
- es_fclose (newfp);
+ _keybox_ll_close (fp);
+ _keybox_ll_close (newfp);
goto leave;
}
}
@@ -275,16 +275,16 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
if (es_fwrite (buffer, nread, 1, newfp) != 1)
{
rc = gpg_error_from_syserror ();
- es_fclose (fp);
- es_fclose (newfp);
+ _keybox_ll_close (fp);
+ _keybox_ll_close (newfp);
goto leave;
}
}
if (es_ferror (fp))
{
rc = gpg_error_from_syserror ();
- es_fclose (fp);
- es_fclose (newfp);
+ _keybox_ll_close (fp);
+ _keybox_ll_close (newfp);
goto leave;
}
@@ -292,9 +292,9 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
rc = _keybox_read_blob (NULL, fp, NULL);
if (rc)
{
- es_fclose (fp);
- es_fclose (newfp);
- return rc;
+ _keybox_ll_close (fp);
+ _keybox_ll_close (newfp);
+ goto leave;
}
}
@@ -304,9 +304,9 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
rc = _keybox_write_blob (blob, newfp, NULL);
if (rc)
{
- es_fclose (fp);
- es_fclose (newfp);
- return rc;
+ _keybox_ll_close (fp);
+ _keybox_ll_close (newfp);
+ goto leave;
}
}
@@ -318,32 +318,30 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
if (es_fwrite (buffer, nread, 1, newfp) != 1)
{
rc = gpg_error_from_syserror ();
- es_fclose (fp);
- es_fclose (newfp);
+ _keybox_ll_close (fp);
+ _keybox_ll_close (newfp);
goto leave;
}
}
if (es_ferror (fp))
{
rc = gpg_error_from_syserror ();
- es_fclose (fp);
- es_fclose (newfp);
+ _keybox_ll_close (fp);
+ _keybox_ll_close (newfp);
goto leave;
}
}
/* Close both files. */
- if (es_fclose(fp))
- {
- rc = gpg_error_from_syserror ();
- es_fclose (newfp);
- goto leave;
- }
- if (es_fclose(newfp))
+ rc = _keybox_ll_close (fp);
+ if (rc)
{
- rc = gpg_error_from_syserror ();
+ _keybox_ll_close (newfp);
goto leave;
}
+ rc = _keybox_ll_close (newfp);
+ if (rc)
+ goto leave;
rc = rename_tmp_file (bakfname, tmpfname, fname, secret);
@@ -491,6 +489,7 @@ keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert,
int
keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value)
{
+ gpg_error_t err;
off_t off;
const char *fname;
estream_t fp;
@@ -525,9 +524,10 @@ keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value)
off += flag_pos;
_keybox_close_file (hd);
- fp = es_fopen (hd->kb->fname, "r+b");
- if (!fp)
- return gpg_error_from_syserror ();
+
+ err = _keybox_ll_open (&fp, fname, KEYBOX_LL_OPEN_UPDATE);
+ if (err)
+ return err;
ec = 0;
if (es_fseeko (fp, off, SEEK_SET))
@@ -555,10 +555,11 @@ keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value)
}
}
- if (es_fclose (fp))
+ err = _keybox_ll_close (fp);
+ if (err)
{
if (!ec)
- ec = gpg_err_code_from_syserror ();
+ ec = gpg_err_code (err);
}
return gpg_error (ec);
@@ -572,7 +573,7 @@ keybox_delete (KEYBOX_HANDLE hd)
off_t off;
const char *fname;
estream_t fp;
- int rc;
+ int rc, rc2;
if (!hd)
return gpg_error (GPG_ERR_INV_VALUE);
@@ -590,9 +591,9 @@ keybox_delete (KEYBOX_HANDLE hd)
off += 4;
_keybox_close_file (hd);
- fp = es_fopen (hd->kb->fname, "r+b");
- if (!fp)
- return gpg_error_from_syserror ();
+ rc = _keybox_ll_open (&fp, hd->kb->fname, KEYBOX_LL_OPEN_UPDATE);
+ if (rc)
+ return rc;
if (es_fseeko (fp, off, SEEK_SET))
rc = gpg_error_from_syserror ();
@@ -601,10 +602,11 @@ keybox_delete (KEYBOX_HANDLE hd)
else
rc = 0;
- if (es_fclose (fp))
+ rc2 = _keybox_ll_close (fp);
+ if (rc2)
{
if (!rc)
- rc = gpg_error_from_syserror ();
+ rc = rc2;
}
return rc;
@@ -617,7 +619,7 @@ int
keybox_compress (KEYBOX_HANDLE hd)
{
gpg_err_code_t ec;
- int read_rc, rc;
+ int read_rc, rc, rc2;
const char *fname;
estream_t fp, newfp;
char *bakfname = NULL;
@@ -645,14 +647,11 @@ keybox_compress (KEYBOX_HANDLE hd)
if ((ec = gnupg_access (fname, W_OK)))
return gpg_error (ec);
- fp = es_fopen (fname, "rb");
- if (!fp && errno == ENOENT)
+ rc = _keybox_ll_open (&fp, fname, 0);
+ if (gpg_err_code (rc) == GPG_ERR_ENOENT)
return 0; /* Ready. File has been deleted right after the access above. */
- if (!fp)
- {
- rc = gpg_error_from_syserror ();
- return rc;
- }
+ if (rc)
+ return rc;
/* A quick test to see if we need to compress the file at all. We
schedule a compress run after 3 hours. */
@@ -668,7 +667,7 @@ keybox_compress (KEYBOX_HANDLE hd)
if ( (last_maint + 3*3600) > make_timestamp () )
{
- es_fclose (fp);
+ _keybox_ll_close (fp);
_keybox_release_blob (blob);
return 0; /* Compress run not yet needed. */
}
@@ -682,7 +681,7 @@ keybox_compress (KEYBOX_HANDLE hd)
rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
if (rc)
{
- es_fclose (fp);
+ _keybox_ll_close (fp);
return rc;;
}
@@ -771,10 +770,10 @@ keybox_compress (KEYBOX_HANDLE hd)
rc = read_rc;
/* Close both files. */
- if (es_fclose(fp) && !rc)
- rc = gpg_error_from_syserror ();
- if (es_fclose(newfp) && !rc)
- rc = gpg_error_from_syserror ();
+ if ((rc2 = _keybox_ll_close (fp)) && !rc)
+ rc = rc2;
+ if ((rc2 = _keybox_ll_close (newfp)) && !rc)
+ rc = rc2;
/* Rename or remove the temporary file. */
if (rc || !any_changes)
diff --git a/kbx/keybox.h b/kbx/keybox.h
index f90ea1c..adfa5a8 100644
--- a/kbx/keybox.h
+++ b/kbx/keybox.h
@@ -66,6 +66,7 @@ typedef enum
/*-- keybox-init.c --*/
gpg_error_t keybox_register_file (const char *fname, int secret,
void **r_token);
+void keybox_set_buffersize (unsigned int kbytes, int reserved);
int keybox_is_writable (void *token);
KEYBOX_HANDLE keybox_new_openpgp (void *token, int secret);