aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Makefile.am4
-rw-r--r--common/exechelp-w32.c45
-rw-r--r--common/mkstrtable.awk10
-rw-r--r--common/name-value.c87
-rw-r--r--common/name-value.h6
-rw-r--r--common/openpgp-s2k.c2
-rw-r--r--common/sexputil.c9
-rw-r--r--common/t-name-value.c25
-rw-r--r--common/userids.c7
-rw-r--r--common/util.h2
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);