mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
agent: Update the key file only if not changed.
* common/name-value.c (struct name_value_container): Add flag "modified". (nvc_modified): New. (nvc_new): Set flag. (_nvc_add): Set flag. (nvc_delete): Set flag. (nve_set): Add arg PK. Change the caller. Check whether to change at all. * agent/findkey.c (agent_write_private_key): Update only if modified. -- This helps software which uses a file system watcher to track changes to private keys. In particular smartcard triggered changes are a problem for such software because this may at worst trigger another smartcard read. GnuPG-bug-id: 6829
This commit is contained in:
parent
6236a52d0e
commit
5bab257d3a
@ -117,6 +117,8 @@ agent_write_private_key (const unsigned char *grip,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvc_modified (pk, 1); /* Clear that flag after a read. */
|
||||||
|
|
||||||
if (!pk)
|
if (!pk)
|
||||||
{
|
{
|
||||||
/* Key is still in the old format or does not exist - create a
|
/* Key is still in the old format or does not exist - create a
|
||||||
@ -212,7 +214,7 @@ agent_write_private_key (const unsigned char *grip,
|
|||||||
; /* No need to update Token entry. */
|
; /* No need to update Token entry. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
err = nve_set (item, token);
|
err = nve_set (pk, item, token);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -232,6 +234,13 @@ agent_write_private_key (const unsigned char *grip,
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check whether we need to write the file at all. */
|
||||||
|
if (!nvc_modified (pk, 0))
|
||||||
|
{
|
||||||
|
err = 0;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a temporary file for writing. */
|
/* Create a temporary file for writing. */
|
||||||
fname = fname_from_keygrip (grip, 1);
|
fname = fname_from_keygrip (grip, 1);
|
||||||
fp = fname ? es_fopen (fname, "wbx,mode=-rw") : NULL;
|
fp = fname ? es_fopen (fname, "wbx,mode=-rw") : NULL;
|
||||||
|
@ -48,6 +48,7 @@ struct name_value_container
|
|||||||
struct name_value_entry *first;
|
struct name_value_entry *first;
|
||||||
struct name_value_entry *last;
|
struct name_value_entry *last;
|
||||||
unsigned int private_key_mode:1;
|
unsigned int private_key_mode:1;
|
||||||
|
unsigned int modified:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -87,11 +88,15 @@ my_error (gpg_err_code_t ec)
|
|||||||
|
|
||||||
/* Allocation and deallocation. */
|
/* Allocation and deallocation. */
|
||||||
|
|
||||||
/* Allocate a private key container structure. */
|
/* Allocate a name value container structure. */
|
||||||
nvc_t
|
nvc_t
|
||||||
nvc_new (void)
|
nvc_new (void)
|
||||||
{
|
{
|
||||||
return xtrycalloc (1, sizeof (struct name_value_container));
|
nvc_t nvc;
|
||||||
|
nvc = xtrycalloc (1, sizeof (struct name_value_container));
|
||||||
|
if (nvc)
|
||||||
|
nvc->modified = 1;
|
||||||
|
return nvc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -142,6 +147,24 @@ nvc_release (nvc_t pk)
|
|||||||
xfree (pk);
|
xfree (pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the modified-flag of the container and clear it if CLEAR is
|
||||||
|
* set. That flag is set for a new container and set with each
|
||||||
|
* update. */
|
||||||
|
int
|
||||||
|
nvc_modified (nvc_t pk, int clear)
|
||||||
|
{
|
||||||
|
int modified;
|
||||||
|
|
||||||
|
if (!pk)
|
||||||
|
return 0;
|
||||||
|
modified = pk->modified;
|
||||||
|
if (clear)
|
||||||
|
pk->modified = 0;
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Dealing with names and values. */
|
/* Dealing with names and values. */
|
||||||
@ -427,6 +450,8 @@ _nvc_add (nvc_t pk, char *name, char *value, strlist_t raw_value,
|
|||||||
else
|
else
|
||||||
pk->first = pk->last = e;
|
pk->first = pk->last = e;
|
||||||
|
|
||||||
|
pk->modified = 1;
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -476,21 +501,29 @@ nvc_set (nvc_t pk, const char *name, const char *value)
|
|||||||
|
|
||||||
e = nvc_lookup (pk, name);
|
e = nvc_lookup (pk, name);
|
||||||
if (e)
|
if (e)
|
||||||
return nve_set (e, value);
|
return nve_set (pk, e, value);
|
||||||
else
|
else
|
||||||
return nvc_add (pk, name, value);
|
return nvc_add (pk, name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Update entry E to VALUE. */
|
/* Update entry E to VALUE. PK is optional; if given its modified
|
||||||
|
* flag will be updated. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
nve_set (nve_t e, const char *value)
|
nve_set (nvc_t pk, nve_t e, const char *value)
|
||||||
{
|
{
|
||||||
char *v;
|
char *v;
|
||||||
|
|
||||||
if (!e)
|
if (!e)
|
||||||
return GPG_ERR_INV_ARG;
|
return GPG_ERR_INV_ARG;
|
||||||
|
|
||||||
|
if (e->value && value && !strcmp (e->value, value))
|
||||||
|
{
|
||||||
|
/* Setting same value - ignore this call and don't set the
|
||||||
|
* modified flag. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
v = xtrystrdup (value? value:"");
|
v = xtrystrdup (value? value:"");
|
||||||
if (!v)
|
if (!v)
|
||||||
return my_error_from_syserror ();
|
return my_error_from_syserror ();
|
||||||
@ -501,6 +534,8 @@ nve_set (nve_t e, const char *value)
|
|||||||
wipememory (e->value, strlen (e->value));
|
wipememory (e->value, strlen (e->value));
|
||||||
xfree (e->value);
|
xfree (e->value);
|
||||||
e->value = v;
|
e->value = v;
|
||||||
|
if (pk)
|
||||||
|
pk->modified = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -521,6 +556,7 @@ nvc_delete (nvc_t pk, nve_t entry)
|
|||||||
pk->last = entry->prev;
|
pk->last = entry->prev;
|
||||||
|
|
||||||
nve_release (entry, pk->private_key_mode);
|
nve_release (entry, pk->private_key_mode);
|
||||||
|
pk->modified = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete the entries with NAME from PK. */
|
/* Delete the entries with NAME from PK. */
|
||||||
|
@ -50,6 +50,9 @@ nvc_t nvc_new_private_key (void);
|
|||||||
/* Release a name value container structure. */
|
/* Release a name value container structure. */
|
||||||
void nvc_release (nvc_t pk);
|
void nvc_release (nvc_t pk);
|
||||||
|
|
||||||
|
/* Return the modified flag and optionally clear it. */
|
||||||
|
int nvc_modified (nvc_t pk, int clear);
|
||||||
|
|
||||||
/* Get the name. */
|
/* Get the name. */
|
||||||
char *nve_name (nve_t pke);
|
char *nve_name (nve_t pke);
|
||||||
|
|
||||||
@ -91,8 +94,8 @@ gpg_error_t nvc_add (nvc_t pk, const char *name, const char *value);
|
|||||||
first entry is updated. */
|
first entry is updated. */
|
||||||
gpg_error_t nvc_set (nvc_t pk, const char *name, const char *value);
|
gpg_error_t nvc_set (nvc_t pk, const char *name, const char *value);
|
||||||
|
|
||||||
/* Update entry E to VALUE. */
|
/* Update entry E to VALUE. PK is optional. */
|
||||||
gpg_error_t nve_set (nve_t e, const char *value);
|
gpg_error_t nve_set (nvc_t pk, nve_t e, const char *value);
|
||||||
|
|
||||||
/* Delete the given entry from PK. */
|
/* Delete the given entry from PK. */
|
||||||
void nvc_delete (nvc_t pk, nve_t pke);
|
void nvc_delete (nvc_t pk, nve_t pke);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user