diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile.am | 4 | ||||
-rw-r--r-- | common/exechelp-w32.c | 45 | ||||
-rw-r--r-- | common/mkstrtable.awk | 10 | ||||
-rw-r--r-- | common/name-value.c | 87 | ||||
-rw-r--r-- | common/name-value.h | 6 | ||||
-rw-r--r-- | common/openpgp-s2k.c | 2 | ||||
-rw-r--r-- | common/sexputil.c | 9 | ||||
-rw-r--r-- | common/t-name-value.c | 25 | ||||
-rw-r--r-- | common/userids.c | 7 | ||||
-rw-r--r-- | common/util.h | 2 |
10 files changed, 170 insertions, 27 deletions
diff --git a/common/Makefile.am b/common/Makefile.am index b6a6605f1..9e0f10917 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -149,13 +149,13 @@ if MAINTAINER_MODE audit-events.h: Makefile.am mkstrtable.awk exaudit.awk audit.h $(AWK) -f $(srcdir)/exaudit.awk $(srcdir)/audit.h \ | $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \ - -v namespace=eventstr_ > $(srcdir)/audit-events.h + -v pkg_namespace=eventstr_ > $(srcdir)/audit-events.h # Create the status-codes.h include file from status.h status-codes.h: Makefile.am mkstrtable.awk exstatus.awk status.h $(AWK) -f $(srcdir)/exstatus.awk $(srcdir)/status.h \ | $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \ - -v namespace=statusstr_ > $(srcdir)/status-codes.h + -v pkg_namespace=statusstr_ > $(srcdir)/status-codes.h endif # diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index 86b1d6869..ea158a33f 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -856,6 +856,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], STARTUPINFO si; int cr_flags; char *cmdline; + BOOL in_job = FALSE; /* We don't use ENVP. */ @@ -884,6 +885,50 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], | GetPriorityClass (GetCurrentProcess ()) | CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS); + + /* Check if we were spawned as part of a Job. + * In a job we need to add CREATE_BREAKAWAY_FROM_JOB + * to the cr_flags, otherwise our child processes + * are killed when we terminate. */ + if (!IsProcessInJob (GetCurrentProcess(), NULL, &in_job)) + { + log_error ("IsProcessInJob() failed: %s\n", w32_strerror (-1)); + in_job = FALSE; + } + + if (in_job) + { + /* Only try to break away from job if it is allowed, otherwise + * CreateProcess() would fail with an "Access is denied" error. */ + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; + if (!QueryInformationJobObject (NULL, JobObjectExtendedLimitInformation, + &info, sizeof info, NULL)) + { + log_error ("QueryInformationJobObject() failed: %s\n", + w32_strerror (-1)); + } + else if ((info.BasicLimitInformation.LimitFlags & + JOB_OBJECT_LIMIT_BREAKAWAY_OK)) + { + log_debug ("Using CREATE_BREAKAWAY_FROM_JOB flag\n"); + cr_flags |= CREATE_BREAKAWAY_FROM_JOB; + } + else if ((info.BasicLimitInformation.LimitFlags & + JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)) + { + /* The child process should automatically detach from the job. */ + log_debug ("Not using CREATE_BREAKAWAY_FROM_JOB flag; " + "JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK is set\n"); + } + else + { + /* It seems that the child process must remain in the job. + * This is not necessarily an error, although it can cause premature + * termination of the child process when the job is closed. */ + log_debug ("Not using CREATE_BREAKAWAY_FROM_JOB flag\n"); + } + } + /* log_debug ("CreateProcess(detached), path='%s' cmdline='%s'\n", */ /* pgmname, cmdline); */ if (!CreateProcess (pgmname, /* Program to start. */ diff --git a/common/mkstrtable.awk b/common/mkstrtable.awk index b5d4ef07a..60efce8a3 100644 --- a/common/mkstrtable.awk +++ b/common/mkstrtable.awk @@ -76,7 +76,7 @@ # # The variable prefix can be used to prepend a string to each message. # -# The variable namespace can be used to prepend a string to each +# The variable pkg_namespace can be used to prepend a string to each # variable and macro name. BEGIN { @@ -101,7 +101,7 @@ header { print "/* The purpose of this complex string table is to produce"; print " optimal code with a minimum of relocations. */"; print ""; - print "static const char " namespace "msgstr[] = "; + print "static const char " pkg_namespace "msgstr[] = "; header = 0; } else @@ -109,7 +109,7 @@ header { } !header { - sub (/\#.+/, ""); + sub (/#.+/, ""); sub (/[ ]+$/, ""); # Strip trailing space and tab characters. if (/^$/) @@ -149,14 +149,14 @@ END { else print " gettext_noop (\"" prefix last_msgstr "\");"; print ""; - print "static const int " namespace "msgidx[] ="; + print "static const int " pkg_namespace "msgidx[] ="; print " {"; for (i = 0; i < coded_msgs; i++) print " " pos[i] ","; print " " pos[coded_msgs]; print " };"; print ""; - print "#define " namespace "msgidxof(code) (0 ? -1 \\"; + print "#define " pkg_namespace "msgidxof(code) (0 ? -1 \\"; # Gather the ranges. skip = code[0]; diff --git a/common/name-value.c b/common/name-value.c index 5094acd03..989a5b111 100644 --- a/common/name-value.c +++ b/common/name-value.c @@ -514,6 +514,21 @@ nvc_delete (nvc_t pk, nve_t entry) nve_release (entry, pk->private_key_mode); } + +/* Delete the entries with NAME from PK. */ +void +nvc_delete_named (nvc_t pk, const char *name) +{ + nve_t e; + + if (!valid_name (name)) + return; + + while ((e = nvc_lookup (pk, name))) + nvc_delete (pk, e); +} + + /* Lookup and iteration. */ @@ -563,6 +578,25 @@ nve_next_value (nve_t entry, const char *name) return NULL; } + +/* Return the string for the first entry in NVC with NAME. If an + * entry with NAME is missing in NVC or its value is the empty string + * NULL is returned. Note that the The returned string is a pointer + * into NVC. */ +const char * +nvc_get_string (nvc_t nvc, const char *name) +{ + nve_t item; + + if (!nvc) + return NULL; + item = nvc_lookup (nvc, name); + if (!item) + return NULL; + return nve_value (item); +} + + /* Private key handling. */ @@ -778,29 +812,56 @@ nvc_parse_private_key (nvc_t *result, int *errlinep, estream_t stream) } +/* Helper fpr nvc_write. */ +static gpg_error_t +write_one_entry (nve_t entry, estream_t stream) +{ + gpg_error_t err; + strlist_t sl; + + if (entry->name) + es_fputs (entry->name, stream); + + err = assert_raw_value (entry); + if (err) + return err; + + for (sl = entry->raw_value; sl; sl = sl->next) + es_fputs (sl->d, stream); + + if (es_ferror (stream)) + return my_error_from_syserror (); + + return 0; +} + + /* Write a representation of PK to STREAM. */ gpg_error_t nvc_write (nvc_t pk, estream_t stream) { - gpg_error_t err; + gpg_error_t err = 0; nve_t entry; - strlist_t s; + nve_t keyentry = NULL; for (entry = pk->first; entry; entry = entry->next) { - if (entry->name) - es_fputs (entry->name, stream); - - err = assert_raw_value (entry); + if (pk->private_key_mode + && entry->name && !ascii_strcasecmp (entry->name, "Key:")) + { + if (!keyentry) + keyentry = entry; + continue; + } + + err = write_one_entry (entry, stream); if (err) return err; - - for (s = entry->raw_value; s; s = s->next) - es_fputs (s->d, stream); - - if (es_ferror (stream)) - return my_error_from_syserror (); } - return 0; + /* In private key mode we write the Key always last. */ + if (keyentry) + err = write_one_entry (keyentry, stream); + + return err; } diff --git a/common/name-value.h b/common/name-value.h index 5c24b8db1..a6283a649 100644 --- a/common/name-value.h +++ b/common/name-value.h @@ -72,6 +72,9 @@ nve_t nve_next (nve_t entry); /* Get the next entry with the given name. */ nve_t nve_next_value (nve_t entry, const char *name); +/* Return the string for the first entry in NVC with NAME or NULL. */ +const char *nvc_get_string (nvc_t nvc, const char *name); + /* Adding and modifying values. */ @@ -88,6 +91,9 @@ gpg_error_t nvc_set (nvc_t pk, const char *name, const char *value); /* Delete the given entry from PK. */ void nvc_delete (nvc_t pk, nve_t pke); +/* Delete the entries with NAME from PK. */ +void nvc_delete_named (nvc_t pk, const char *name); + /* Private key handling. */ diff --git a/common/openpgp-s2k.c b/common/openpgp-s2k.c index 2b0ba604b..69de76329 100644 --- a/common/openpgp-s2k.c +++ b/common/openpgp-s2k.c @@ -39,7 +39,7 @@ #include "openpgpdefs.h" -/* Pack an s2k iteration count into the form specified in RFC-48800. +/* Pack an s2k iteration count into the form specified in RFC-4880. * If we're in between valid values, round up. */ unsigned char encode_s2k_iterations (int iterations) diff --git a/common/sexputil.c b/common/sexputil.c index d3020e169..f99bc3b18 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -581,9 +581,9 @@ get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen) /* Given the public key S_PKEY, return a new buffer with a descriptive * string for its algorithm. This function may return NULL on memory - * error. */ + * error. If R_ALGOID is not NULL the gcrypt algo id is stored there. */ char * -pubkey_algo_string (gcry_sexp_t s_pkey) +pubkey_algo_string (gcry_sexp_t s_pkey, enum gcry_pk_algos *r_algoid) { const char *prefix; gcry_sexp_t l1; @@ -591,6 +591,9 @@ pubkey_algo_string (gcry_sexp_t s_pkey) int algo; char *result; + if (r_algoid) + *r_algoid = 0; + l1 = gcry_sexp_find_token (s_pkey, "public-key", 0); if (!l1) return xtrystrdup ("E_no_key"); @@ -632,6 +635,8 @@ pubkey_algo_string (gcry_sexp_t s_pkey) else result = xtryasprintf ("X_algo_%d", algo); + if (r_algoid) + *r_algoid = algo; xfree (algoname); return result; } diff --git a/common/t-name-value.c b/common/t-name-value.c index 57f685ffb..13a383ddb 100644 --- a/common/t-name-value.c +++ b/common/t-name-value.c @@ -292,6 +292,7 @@ run_modification_tests (void) { gpg_error_t err; nvc_t pk; + nve_t e; gcry_sexp_t key; char *buf; @@ -344,6 +345,30 @@ run_modification_tests (void) assert (strcmp (buf, "") == 0); xfree (buf); + /* Test whether we can delete an entry by name. */ + err = nvc_add (pk, "Key:", "(3:foo)"); + assert (!err); + e = nvc_lookup (pk, "Key:"); + assert (e); + nvc_delete_named (pk, "Kez:"); /* Delete an inexistant name. */ + e = nvc_lookup (pk, "Key:"); + assert (e); + nvc_delete_named (pk, "Key:"); + e = nvc_lookup (pk, "Key:"); + assert (!e); + + /* Ditto but now whether it deletes all entries with that name. We + * don't use "Key" because that name is special in private key mode. */ + err = nvc_add (pk, "AKey:", "A-value"); + assert (!err); + err = nvc_add (pk, "AKey:", "B-value"); + assert (!err); + e = nvc_lookup (pk, "AKey:"); + assert (e); + nvc_delete_named (pk, "AKey:"); + e = nvc_lookup (pk, "AKey:"); + assert (!e); + nvc_set (pk, "Foo:", "A really long value spanning across multiple lines" " that has to be wrapped at a convenient space."); buf = nvc_to_string (pk); diff --git a/common/userids.c b/common/userids.c index 181b48866..55bd85546 100644 --- a/common/userids.c +++ b/common/userids.c @@ -380,8 +380,10 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack) } else if (!hexprefix) { - /* The fingerprint in an X.509 listing is often delimited by - colons, so we try to single this case out. */ + /* The fingerprint of an X.509 listing is often delimited by + * colons, so we try to single this case out. Note that the + * OpenPGP bang suffix is not supported here. */ + desc->exact = 0; mode = 0; hexlength = strspn (s, ":0123456789abcdefABCDEF"); if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) @@ -454,7 +456,6 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack) } if (!mode) /* Default to substring search. */ { - desc->exact = 0; desc->u.name = s; mode = KEYDB_SEARCH_MODE_SUBSTR; } diff --git a/common/util.h b/common/util.h index 8895137ec..bd6cd1ff5 100644 --- a/common/util.h +++ b/common/util.h @@ -192,7 +192,7 @@ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata, int get_pk_algo_from_key (gcry_sexp_t key); int get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen); -char *pubkey_algo_string (gcry_sexp_t s_pkey); +char *pubkey_algo_string (gcry_sexp_t s_pkey, enum gcry_pk_algos *r_algoid); /*-- convert.c --*/ int hex2bin (const char *string, void *buffer, size_t length); |