1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

The keybox gets now compressed after 3 hours and ephemeral

stored certificates are deleted after about a day.
This commit is contained in:
Werner Koch 2004-04-26 08:09:25 +00:00
parent cbc5ce3ea4
commit 6aaceac7fe
14 changed files with 413 additions and 57 deletions

View file

@ -1,5 +1,5 @@
/* keybox-update.c - keybox update operations
* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
* Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -23,6 +23,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#include "keybox-defs.h"
@ -193,29 +194,30 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
fp = fopen (fname, "rb");
if (mode == 1 && !fp && errno == ENOENT)
{ /* insert mode but file does not exist: create a new keybox file */
{
/* Insert mode but file does not exist:
Create a new keybox file. */
newfp = fopen (fname, "wb");
if (!newfp )
{
return gpg_error (gpg_err_code_from_errno (errno));
}
return gpg_error (gpg_err_code_from_errno (errno));
rc = _keybox_write_header_blob (newfp);
if (rc)
return rc;
rc = _keybox_write_blob (blob, newfp);
if (rc)
{
return rc;
}
return rc;
if ( fclose (newfp) )
{
return gpg_error (gpg_err_code_from_errno (errno));
}
return gpg_error (gpg_err_code_from_errno (errno));
/* if (chmod( fname, S_IRUSR | S_IWUSR )) */
/* { */
/* log_debug ("%s: chmod failed: %s\n", fname, strerror(errno) ); */
/* return KEYBOX_File_Error; */
/* } */
return 0; /* ready */
return 0; /* Ready. */
}
if (!fp)
@ -224,7 +226,7 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
goto leave;
}
/* create the new file */
/* Create the new file. */
rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
if (rc)
{
@ -235,7 +237,7 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
/* prepare for insert */
if (mode == 1)
{
/* copy everything to the new file */
/* Copy everything to the new file. */
while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 )
{
if (fwrite (buffer, nread, 1, newfp) != 1)
@ -251,19 +253,19 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
}
}
/* prepare for delete or update */
/* Prepare for delete or update. */
if ( mode == 2 || mode == 3 )
{
off_t current = 0;
/* copy first part to the new file */
/* Copy first part to the new file. */
while ( current < start_offset )
{
nbytes = DIM(buffer);
if (current + nbytes > start_offset)
nbytes = start_offset - current;
nread = fread (buffer, 1, nbytes, fp);
if (!fread)
if (!nread)
break;
current += nread;
@ -279,13 +281,13 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
goto leave;
}
/* skip this blob */
/* Skip this blob. */
rc = _keybox_read_blob (NULL, fp);
if (rc)
return rc;
}
/* Do an insert or update */
/* Do an insert or update. */
if ( mode == 1 || mode == 3 )
{
rc = _keybox_write_blob (blob, newfp);
@ -293,7 +295,7 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
return rc;
}
/* copy the rest of the packet for an delete or update */
/* Copy the rest of the packet for an delete or update. */
if (mode == 2 || mode == 3)
{
while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 )
@ -311,7 +313,7 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
}
}
/* close both files */
/* Close both files. */
if (fclose(fp))
{
rc = gpg_error (gpg_err_code_from_errno (errno));
@ -334,7 +336,6 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
#ifdef KEYBOX_WITH_X509
int
keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert,
@ -352,7 +353,7 @@ keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert,
if (!fname)
return gpg_error (GPG_ERR_INV_HANDLE);
/* close this one otherwise we will mess up the position for a next
/* Close this one otherwise we will mess up the position for a next
search. Fixme: it would be better to adjust the position after
the write opertions. */
if (hd->fp)
@ -517,3 +518,181 @@ keybox_delete (KEYBOX_HANDLE hd)
}
/* Compress the keybox file. This should be run with the file
locked. */
int
keybox_compress (KEYBOX_HANDLE hd)
{
int read_rc, rc;
const char *fname;
FILE *fp, *newfp;
char *bakfname = NULL;
char *tmpfname = NULL;
int first_blob;
KEYBOXBLOB blob = NULL;
u32 cut_time;
int any_changes = 0;
int skipped_deleted;
if (!hd)
return gpg_error (GPG_ERR_INV_HANDLE);
if (!hd->kb)
return gpg_error (GPG_ERR_INV_HANDLE);
if (hd->secret)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
fname = hd->kb->fname;
if (!fname)
return gpg_error (GPG_ERR_INV_HANDLE);
if (hd->fp)
{
fclose (hd->fp);
hd->fp = NULL;
}
/* Open the source file. Because we do a rename, we have to check the
permissions of the file */
if (access (fname, W_OK))
return gpg_error (gpg_err_code_from_errno (errno));
fp = fopen (fname, "rb");
if (!fp && errno == ENOENT)
return 0; /* Ready. File has been deleted right after the access above. */
if (!fp)
{
rc = gpg_error (gpg_err_code_from_errno (errno));
return rc;
}
/* A quick test to see if we need to compress the file at all. We
schedule a compress run after 3 hours. */
if ( !_keybox_read_blob (&blob, fp) )
{
const unsigned char *buffer;
size_t length;
buffer = _keybox_get_blob_image (blob, &length);
if (length > 4 && buffer[4] == BLOBTYPE_HEADER)
{
u32 last_maint = ((buffer[20] << 24) | (buffer[20+1] << 16)
| (buffer[20+2] << 8) | (buffer[20+3]));
if ( (last_maint + 3*3600) > time (NULL) )
{
fclose (fp);
_keybox_release_blob (blob);
return 0; /* Compress run not yet needed. */
}
}
_keybox_release_blob (blob);
rewind (fp);
}
/* Create the new file. */
rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
if (rc)
{
fclose(fp);
return rc;;
}
/* Processing loop. By reading using _keybox_read_blob we
automagically skip and blobs flagged as deleted. Thus what we
only have to do is to check all ephemeral flagged blocks whether
their time has come and write out all other blobs. */
cut_time = time(NULL) - 86400;
first_blob = 1;
skipped_deleted = 0;
for (rc=0; !(read_rc = _keybox_read_blob2 (&blob, fp, &skipped_deleted));
_keybox_release_blob (blob), blob = NULL )
{
unsigned int blobflags;
const unsigned char *buffer;
size_t length, pos, size;
u32 created_at;
if (skipped_deleted)
any_changes = 1;
buffer = _keybox_get_blob_image (blob, &length);
if (first_blob)
{
first_blob = 0;
if (length > 4 && buffer[4] == BLOBTYPE_HEADER)
{
/* Write out the blob with an updated maintenance time stamp. */
_keybox_update_header_blob (blob);
rc = _keybox_write_blob (blob, newfp);
if (rc)
break;
continue;
}
/* The header blob is missing. Insert it. */
rc = _keybox_write_header_blob (newfp);
if (rc)
break;
any_changes = 1;
}
else if (length > 4 && buffer[4] == BLOBTYPE_HEADER)
{
/* Oops: There is another header record - remove it. */
any_changes = 1;
continue;
}
if (_keybox_get_flag_location (buffer, length,
KEYBOX_FLAG_BLOB, &pos, &size)
|| size != 2)
{
rc = gpg_error (GPG_ERR_BUG);
break;
}
blobflags = ((buffer[pos] << 8) | (buffer[pos+1]));
if ((blobflags & 2))
{
/* This is an ephemeral blob. */
if (_keybox_get_flag_location (buffer, length,
KEYBOX_FLAG_CREATED_AT, &pos, &size)
|| size != 4)
created_at = 0; /* oops. */
else
created_at = ((buffer[pos] << 24) | (buffer[pos+1] << 16)
| (buffer[pos+2] << 8) | (buffer[pos+3]));
if (created_at && created_at < cut_time)
{
any_changes = 1;
continue; /* Skip this blob. */
}
}
rc = _keybox_write_blob (blob, newfp);
if (rc)
break;
}
if (skipped_deleted)
any_changes = 1;
_keybox_release_blob (blob); blob = NULL;
if (!rc && read_rc == -1)
rc = 0;
else if (!rc)
rc = read_rc;
/* Close both files. */
if (fclose(fp) && !rc)
rc = gpg_error (gpg_err_code_from_errno (errno));
if (fclose(newfp) && !rc)
rc = gpg_error (gpg_err_code_from_errno (errno));
/* Rename or remove the temporary file. */
if (rc || !any_changes)
remove (tmpfname);
else
rc = rename_tmp_file (bakfname, tmpfname, fname, hd->secret);
xfree(bakfname);
xfree(tmpfname);
return rc;
}