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:
parent
1676203199
commit
620abc1658
@ -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.
|
||||
|
@ -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) {}
|
||||
|
161
g10/keydb.c
161
g10/keydb.c
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user