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

* keydb.c (keydb_add_resource): Factored keyring creation out to ..

(maybe_create_keyring): .. new.  Make sure that we do the checks
in a locked state.  Problem reported by Stefan Haller.
This commit is contained in:
Werner Koch 2004-08-13 17:00:05 +00:00
parent 1676203199
commit 620abc1658
6 changed files with 149 additions and 62 deletions

View File

@ -1,3 +1,11 @@
2004-08-11 Werner Koch <wk@g10code.de>
* gpgv.c (destroy_dotlock): New stub.
* keydb.c (keydb_add_resource): Factored keyring creation out to ..
(maybe_create_keyring): .. new. Make sure that we do the checks
in a locked state. Problem reported by Stefan Haller.
2004-08-09 Werner Koch <wk@g10code.de>
* Makefile.am (LDADD): Replaced INTLLIBS by LIBINTL.

View File

@ -390,6 +390,7 @@ int tty_no_terminal(int onoff) {return 0;}
/* We do not do any locking, so use these stubs here */
void disable_dotlock(void) {}
DOTLOCK create_dotlock( const char *file_to_lock ) { return NULL; }
void destroy_dotlock (DOTLOCK h) { };
int make_dotlock( DOTLOCK h, long timeout ) { return 0;}
int release_dotlock( DOTLOCK h ) {return 0;}
void remove_lockfiles(void) {}

View File

@ -1,5 +1,5 @@
/* keydb.c - key database dispatcher
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -69,6 +69,111 @@ static int lock_all (KEYDB_HANDLE hd);
static void unlock_all (KEYDB_HANDLE hd);
/* Handle the creation of a keyring if it does not yet exist. Take
into acount that other processes might have the keyring alread
locked. This lock check does not work if the directory itself is
not yet available. */
static int
maybe_create_keyring (char *filename, int force)
{
DOTLOCK lockhd;
IOBUF iobuf;
int rc;
mode_t oldmask;
char *last_slash_in_filename;
/* A quick test whether the filename already exists. */
if (!access (filename, F_OK))
return 0;
/* If we don't want to create a new file at all, there is no need to
go any further - bail out right here. */
if (!force)
return G10ERR_OPEN_FILE;
/* To avoid races with other instances of gpg trying to create or
update the keyring (it is removed during an update for a short
time), we do the next stuff in a locked state. */
lockhd = create_dotlock (filename);
if (!lockhd)
{
/* A reason for this to fail is that the directory is not
writable. However, this whole locking stuff does not make
sense if this is the case. An empty non-writable directory
with no keyring is not really useful at all. */
if (opt.verbose)
log_info ("can't allocate lock for `%s'\n", filename );
if (!force)
return G10ERR_OPEN_FILE;
else
return G10ERR_GENERAL;
}
if ( make_dotlock (lockhd, -1) )
{
/* This is something bad. Probably a stale lockfile. */
log_info ("can't lock `%s'\n", filename );
rc = G10ERR_GENERAL;
goto leave;
}
/* Now the real test while we are locked. */
if (!access(filename, F_OK))
{
rc = 0; /* Okay, we may access the file now. */
goto leave;
}
/* The file does not yet exist, create it now. */
last_slash_in_filename = strrchr (filename, DIRSEP_C);
*last_slash_in_filename = 0;
if (access(filename, F_OK))
{ /* On the first time we try to create the default
homedir and check again. */
static int tried;
if (!tried)
{
tried = 1;
try_make_homedir (filename);
}
if (access (filename, F_OK))
{
rc = G10ERR_OPEN_FILE;
*last_slash_in_filename = DIRSEP_C;
goto leave;
}
}
*last_slash_in_filename = DIRSEP_C;
oldmask = umask (077);
iobuf = iobuf_create (filename);
umask (oldmask);
if (!iobuf)
{
log_error ( _("error creating keyring `%s': %s\n"),
filename, strerror(errno));
rc = G10ERR_OPEN_FILE;
goto leave;
}
if (!opt.quiet)
log_info (_("keyring `%s' created\n"), filename);
iobuf_close (iobuf);
/* Must invalidate that ugly cache */
iobuf_ioctl (NULL, 2, 0, filename);
rc = 0;
leave:
release_dotlock (lockhd);
destroy_dotlock (lockhd);
return rc;
}
/*
* Register a resource (which currently may only be a keyring file).
* The first keyring which is added by this function is
@ -81,7 +186,6 @@ keydb_add_resource (const char *url, int force, int secret)
{
static int any_secret, any_public;
const char *resname = url;
IOBUF iobuf = NULL;
char *filename = NULL;
int rc = 0;
KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
@ -145,56 +249,9 @@ keydb_add_resource (const char *url, int force, int secret)
goto leave;
case KEYDB_RESOURCE_TYPE_KEYRING:
if (access(filename, F_OK))
{ /* file does not exist */
mode_t oldmask;
char *last_slash_in_filename;
if (!force)
{
rc = G10ERR_OPEN_FILE;
goto leave;
}
last_slash_in_filename = strrchr (filename, DIRSEP_C);
*last_slash_in_filename = 0;
if (access(filename, F_OK))
{ /* On the first time we try to create the default
homedir and check again. */
static int tried;
if (!tried)
{
tried = 1;
try_make_homedir (filename);
}
if (access (filename, F_OK))
{
rc = G10ERR_OPEN_FILE;
*last_slash_in_filename = DIRSEP_C;
goto leave;
}
}
*last_slash_in_filename = DIRSEP_C;
oldmask=umask(077);
iobuf = iobuf_create (filename);
umask(oldmask);
if (!iobuf)
{
log_error ( _("error creating keyring `%s': %s\n"),
filename, strerror(errno));
rc = G10ERR_OPEN_FILE;
goto leave;
}
if (!opt.quiet)
log_info (_("keyring `%s' created\n"), filename);
iobuf_close (iobuf);
iobuf = NULL;
/* must invalidate that ugly cache */
iobuf_ioctl (NULL, 2, 0, (char*)filename);
} /* end file creation */
rc = maybe_create_keyring (filename, force);
if (rc)
goto leave;
token = keyring_register_filename (filename, secret);
if (!token)

View File

@ -144,6 +144,7 @@ typedef struct dotlock_handle *DOTLOCK;
void disable_dotlock(void);
DOTLOCK create_dotlock( const char *file_to_lock );
void destroy_dotlock ( DOTLOCK h );
int make_dotlock( DOTLOCK h, long timeout );
int release_dotlock( DOTLOCK h );
void remove_lockfiles (void);

View File

@ -1,3 +1,8 @@
2004-08-11 Werner Koch <wk@g10code.de>
* dotlock.c (destroy_dotlock): New.
(remove_lockfiles): Implement in terms of destroy_dotlock.
2004-08-09 Werner Koch <wk@g10code.de>
* Makefile.am (http-test): Replaced INTLLIBS by LIBINTL.
@ -1105,7 +1110,7 @@ Fri Feb 13 15:14:13 1998 Werner Koch (wk@isil.d.shuttle.de)
Copyright 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
Copyright 1998,1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without

View File

@ -1,5 +1,5 @@
/* dotlock.c - dotfile locking
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -197,6 +197,28 @@ create_dotlock( const char *file_to_lock )
return h;
}
void
destroy_dotlock ( DOTLOCK h )
{
#if !defined (HAVE_DOSISH_SYSTEM)
if ( h )
{
if (!h->disable)
{
if (h->locked)
unlink (h->lockname);
unlink (h->tname);
m_free (h->tname);
m_free (h->lockname);
}
m_free(h);
}
#endif
}
static int
maybe_deadlock( DOTLOCK h )
{
@ -407,14 +429,7 @@ remove_lockfiles()
while( h ) {
h2 = h->next;
if( !h->disable ) {
if( h->locked )
unlink( h->lockname );
unlink(h->tname);
m_free(h->tname);
m_free(h->lockname);
}
m_free(h);
destroy_dotlock (h);
h = h2;
}
#endif