diff options
author | Werner Koch <wk@gnupg.org> | 2009-04-03 12:34:22 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2009-04-03 12:34:22 +0200 |
commit | 7c98dad98e838d089261716a3823b7be53728fd3 (patch) | |
tree | 995baac48b0d8845cab6cf522eb1a43d16e325b8 /g10/keyring.c | |
parent | Print the card's S/N in a secret key listing. (diff) | |
download | gnupg2-7c98dad98e838d089261716a3823b7be53728fd3.tar.xz gnupg2-7c98dad98e838d089261716a3823b7be53728fd3.zip |
Make gpgv error message about a missing keyring more useful. This fixes
Debian#494040. Also implement readonly semantic for extra safety.
Diffstat (limited to 'g10/keyring.c')
-rw-r--r-- | g10/keyring.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/g10/keyring.c b/g10/keyring.c index 00a5bb986..c01834a6a 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -50,9 +50,11 @@ typedef struct off_item **OffsetHashTable; typedef struct keyring_name *KR_NAME; -struct keyring_name { +struct keyring_name +{ struct keyring_name *next; int secret; + int readonly; DOTLOCK lockhd; int is_locked; int did_full_scan; @@ -199,7 +201,8 @@ update_offset_hash_table_from_kb (OffsetHashTable tbl, KBNODE node, off_t off) * if a new keyring was registered. */ int -keyring_register_filename (const char *fname, int secret, void **ptr) +keyring_register_filename (const char *fname, int secret, int readonly, + void **ptr) { KR_NAME kr; @@ -210,8 +213,11 @@ keyring_register_filename (const char *fname, int secret, void **ptr) { if (same_file_p (kr->fname, fname)) { + /* Already registered. */ + if (readonly) + kr->readonly = 1; *ptr=kr; - return 0; /* Already registered. */ + return 0; } } @@ -221,6 +227,7 @@ keyring_register_filename (const char *fname, int secret, void **ptr) kr = xmalloc (sizeof *kr + strlen (fname)); strcpy (kr->fname, fname); kr->secret = !!secret; + kr->readonly = readonly; kr->lockhd = NULL; kr->is_locked = 0; kr->did_full_scan = 0; @@ -242,7 +249,7 @@ keyring_is_writable (void *token) { KR_NAME r = token; - return r? !access (r->fname, W_OK) : 0; + return r? (r->readonly || !access (r->fname, W_OK)) : 0; } @@ -499,6 +506,9 @@ keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb) if (!hd->found.kr) return -1; /* no successful prior search */ + if (hd->found.kr->readonly) + return gpg_error (GPG_ERR_EACCES); + if (!hd->found.n_packets) { /* need to know the number of packets - do a dummy get_keyblock*/ rc = keyring_get_keyblock (hd, NULL); @@ -540,16 +550,24 @@ keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb) if (!hd) fname = NULL; else if (hd->found.kr) + { fname = hd->found.kr->fname; + if (hd->found.kr->readonly) + return gpg_error (GPG_ERR_EACCES); + } else if (hd->current.kr) + { fname = hd->current.kr->fname; + if (hd->current.kr->readonly) + return gpg_error (GPG_ERR_EACCES); + } else fname = hd->resource? hd->resource->fname:NULL; if (!fname) return G10ERR_GENERAL; - /* close this one otherwise we will lose the position for + /* Close this one otherwise we will lose the position for * a next search. Fixme: it would be better to adjust the position * after the write opertions. */ @@ -575,6 +593,9 @@ keyring_delete_keyblock (KEYRING_HANDLE hd) if (!hd->found.kr) return -1; /* no successful prior search */ + if (hd->found.kr->readonly) + return gpg_error (GPG_ERR_EACCES); + if (!hd->found.n_packets) { /* need to know the number of packets - do a dummy get_keyblock*/ rc = keyring_get_keyblock (hd, NULL); |