summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-02-09 16:00:19 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-02-09 16:00:19 +0900
commitd9787447fe6a57e39113b60305b4ab672b9ba897 (patch)
tree6c925adf6340a1a5ab43d9048ca4b27eae819cd6 /tools
parentf77eedfaad1525168ca8593a3eb43ef157cd2891 (diff)
downloadgpg2-d9787447fe6a57e39113b60305b4ab672b9ba897.tar.gz
gpg2-d9787447fe6a57e39113b60305b4ab672b9ba897.tar.bz2
gpg2-d9787447fe6a57e39113b60305b4ab672b9ba897.zip
Imported Upstream version 2.1.19upstream/2.1.19
Diffstat (limited to 'tools')
-rw-r--r--tools/gpg-connect-agent.c22
-rw-r--r--tools/gpg-wks-client.c90
-rw-r--r--tools/gpg-wks-server.c27
-rw-r--r--tools/gpg-wks.h4
-rw-r--r--tools/gpgconf-comp.c275
-rw-r--r--tools/gpgconf.c2
-rw-r--r--tools/gpgparsemail.c2
-rw-r--r--tools/gpgtar.c4
-rwxr-xr-xtools/mail-signed-keys2
-rw-r--r--tools/mime-parser.c25
-rw-r--r--tools/mime-parser.h2
-rw-r--r--tools/symcryptrun.c4
-rw-r--r--tools/wks-receive.c49
13 files changed, 330 insertions, 178 deletions
diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c
index a5413cf..59e2192 100644
--- a/tools/gpg-connect-agent.c
+++ b/tools/gpg-connect-agent.c
@@ -187,7 +187,7 @@ static assuan_context_t start_agent (void);
-/* Print usage information and and provide strings for help. */
+/* Print usage information and provide strings for help. */
static const char *
my_strusage( int level )
{
@@ -1155,7 +1155,7 @@ main (int argc, char **argv)
int rc;
int cmderr;
const char *opt_run = NULL;
- FILE *script_fp = NULL;
+ gpgrt_stream_t script_fp = NULL;
int use_tty, keep_line;
struct {
int collecting;
@@ -1271,7 +1271,7 @@ main (int argc, char **argv)
"--tcp-socket", "--raw-socket");
}
- if (opt_run && !(script_fp = fopen (opt_run, "r")))
+ if (opt_run && !(script_fp = gpgrt_fopen (opt_run, "r")))
{
log_error ("cannot open run file '%s': %s\n",
opt_run, strerror (errno));
@@ -1425,15 +1425,15 @@ main (int argc, char **argv)
linesize = 0;
keep_line = 1;
}
- n = read_line (script_fp? script_fp:stdin,
- &line, &linesize, &maxlength);
+ n = gpgrt_read_line (script_fp ? script_fp : gpgrt_stdin,
+ &line, &linesize, &maxlength);
}
if (n < 0)
{
log_error (_("error reading input: %s\n"), strerror (errno));
if (script_fp)
{
- fclose (script_fp);
+ gpgrt_fclose (script_fp);
script_fp = NULL;
log_error ("stopping script execution\n");
continue;
@@ -1445,7 +1445,7 @@ main (int argc, char **argv)
/* EOF */
if (script_fp)
{
- fclose (script_fp);
+ gpgrt_fclose (script_fp);
script_fp = NULL;
if (opt.verbose)
log_info ("end of script\n");
@@ -1683,17 +1683,17 @@ main (int argc, char **argv)
log_error ("syntax error in run command\n");
if (script_fp)
{
- fclose (script_fp);
+ gpgrt_fclose (script_fp);
script_fp = NULL;
}
}
else if (script_fp)
{
log_error ("cannot nest run commands - stop\n");
- fclose (script_fp);
+ gpgrt_fclose (script_fp);
script_fp = NULL;
}
- else if (!(script_fp = fopen (p, "r")))
+ else if (!(script_fp = gpgrt_fopen (p, "r")))
{
log_error ("cannot open run file '%s': %s\n",
p, strerror (errno));
@@ -1864,7 +1864,7 @@ main (int argc, char **argv)
if ((rc || cmderr) && script_fp)
{
log_error ("stopping script execution\n");
- fclose (script_fp);
+ gpgrt_fclose (script_fp);
script_fp = NULL;
}
diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c
index 5814b40..c31e3a1 100644
--- a/tools/gpg-wks-client.c
+++ b/tools/gpg-wks-client.c
@@ -129,7 +129,7 @@ static gpg_error_t command_receive_cb (void *opaque,
-/* Print usage information and and provide strings for help. */
+/* Print usage information and provide strings for help. */
static const char *
my_strusage( int level )
{
@@ -373,6 +373,7 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec)
log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
goto leave;
}
+
/* Prefix the key with the MIME content type. */
es_fputs ("Content-Type: application/pgp-keys\n"
"\n", key);
@@ -437,20 +438,38 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec)
+struct decrypt_stream_parm_s
+{
+ char *fpr;
+ char *mainfpr;
+ int otrust;
+};
+
static void
decrypt_stream_status_cb (void *opaque, const char *keyword, char *args)
{
- (void)opaque;
+ struct decrypt_stream_parm_s *decinfo = opaque;
if (DBG_CRYPTO)
log_debug ("gpg status: %s %s\n", keyword, args);
-}
+ if (!strcmp (keyword, "DECRYPTION_KEY") && !decinfo->fpr)
+ {
+ char *fields[3];
+ if (split_fields (args, fields, DIM (fields)) >= 3)
+ {
+ decinfo->fpr = xstrdup (fields[0]);
+ decinfo->mainfpr = xstrdup (fields[1]);
+ decinfo->otrust = *fields[2];
+ }
+ }
+}
/* Decrypt the INPUT stream to a new stream which is stored at success
* at R_OUTPUT. */
static gpg_error_t
-decrypt_stream (estream_t *r_output, estream_t input)
+decrypt_stream (estream_t *r_output, struct decrypt_stream_parm_s *decinfo,
+ estream_t input)
{
gpg_error_t err;
ccparray_t ccp;
@@ -458,6 +477,7 @@ decrypt_stream (estream_t *r_output, estream_t input)
estream_t output;
*r_output = NULL;
+ memset (decinfo, 0, sizeof *decinfo);
output = es_fopenmem (0, "w+b");
if (!output)
@@ -492,7 +512,9 @@ decrypt_stream (estream_t *r_output, estream_t input)
}
err = gnupg_exec_tool_stream (opt.gpg_program, argv, input,
NULL, output,
- decrypt_stream_status_cb, NULL);
+ decrypt_stream_status_cb, decinfo);
+ if (!err && (!decinfo->fpr || !decinfo->mainfpr || !decinfo->otrust))
+ err = gpg_error (GPG_ERR_INV_ENGINE);
if (err)
{
log_error ("decryption failed: %s\n", gpg_strerror (err));
@@ -506,6 +528,12 @@ decrypt_stream (estream_t *r_output, estream_t input)
output = NULL;
leave:
+ if (err)
+ {
+ xfree (decinfo->fpr);
+ xfree (decinfo->mainfpr);
+ memset (decinfo, 0, sizeof *decinfo);
+ }
es_fclose (output);
xfree (argv);
return err;
@@ -749,8 +777,9 @@ command_send (const char *fingerprint, char *userid)
if (err)
goto leave;
- /* Tell server that we support draft version 3. */
- err = mime_maker_add_header (mime, "Wks-Draft-Version", "3");
+ /* Tell server which draft we support. */
+ err = mime_maker_add_header (mime, "Wks-Draft-Version",
+ STR2(WKS_DRAFT_VERSION));
if (err)
goto leave;
@@ -948,6 +977,10 @@ send_confirmation_response (const char *sender, const char *address,
err = mime_maker_add_header (mime, "Subject", "Key publication confirmation");
if (err)
goto leave;
+ err = mime_maker_add_header (mime, "Wks-Draft-Version",
+ STR2(WKS_DRAFT_VERSION));
+ if (err)
+ goto leave;
if (encrypt)
{
@@ -998,9 +1031,11 @@ send_confirmation_response (const char *sender, const char *address,
/* Reply to a confirmation request. The MSG has already been
- * decrypted and we only need to send the nonce back. */
+ * decrypted and we only need to send the nonce back. MAINFPR is
+ * either NULL or the primary key fingerprint of the key used to
+ * decrypt the request. */
static gpg_error_t
-process_confirmation_request (estream_t msg)
+process_confirmation_request (estream_t msg, const char *mainfpr)
{
gpg_error_t err;
nvc_t nvc;
@@ -1044,8 +1079,20 @@ process_confirmation_request (estream_t msg)
}
fingerprint = value;
- /* FIXME: Check that the fingerprint matches the key used to decrypt the
- * message. */
+ /* Check that the fingerprint matches the key used to decrypt the
+ * message. In --read mode or with the old format we don't have the
+ * decryption key; thus we can't bail out. */
+ if (!mainfpr || ascii_strcasecmp (mainfpr, fingerprint))
+ {
+ log_info ("target fingerprint: %s\n", fingerprint);
+ log_info ("but decrypted with: %s\n", mainfpr);
+ log_error ("confirmation request not decrypted with target key\n");
+ if (mainfpr)
+ {
+ err = gpg_error (GPG_ERR_INV_DATA);
+ goto leave;
+ }
+ }
/* Get the address. */
if (!((item = nvc_lookup (nvc, "address:")) && (value = nve_value (item))
@@ -1058,10 +1105,7 @@ process_confirmation_request (estream_t msg)
}
address = value;
/* FIXME: Check that the "address" matches the User ID we want to
- * publish. Also get the "fingerprint" and compare that to our to
- * be published key. Further we should make sure that we actually
- * decrypted using that fingerprint (which is a bit problematic if
- * --read is used). */
+ * publish. */
/* Get the sender. */
if (!((item = nvc_lookup (nvc, "sender:")) && (value = nve_value (item))
@@ -1130,14 +1174,24 @@ read_confirmation_request (estream_t msg)
}
if (c != '-')
- err = process_confirmation_request (msg);
+ err = process_confirmation_request (msg, NULL);
else
{
- err = decrypt_stream (&plaintext, msg);
+ struct decrypt_stream_parm_s decinfo;
+
+ err = decrypt_stream (&plaintext, &decinfo, msg);
if (err)
log_error ("decryption failed: %s\n", gpg_strerror (err));
+ else if (decinfo.otrust != 'u')
+ {
+ err = gpg_error (GPG_ERR_WRONG_SECKEY);
+ log_error ("key used to decrypt the confirmation request"
+ " was not generated by us\n");
+ }
else
- err = process_confirmation_request (plaintext);
+ err = process_confirmation_request (plaintext, decinfo.mainfpr);
+ xfree (decinfo.fpr);
+ xfree (decinfo.mainfpr);
}
es_fclose (plaintext);
diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c
index 1a91858..0376cce 100644
--- a/tools/gpg-wks-server.c
+++ b/tools/gpg-wks-server.c
@@ -133,7 +133,7 @@ static gpg_error_t command_cron (void);
-/* Print usage information and and provide strings for help. */
+/* Print usage information and provide strings for help. */
static const char *
my_strusage( int level )
{
@@ -915,6 +915,18 @@ send_confirmation_request (server_ctx_t ctx,
err = mime_maker_add_header (mime, "Subject", "Confirm your key publication");
if (err)
goto leave;
+
+ err = mime_maker_add_header (mime, "Wks-Draft-Version",
+ STR2(WKS_DRAFT_VERSION));
+ if (err)
+ goto leave;
+
+ /* Help Enigmail to identify messages. Note that this is in no way
+ * secured. */
+ err = mime_maker_add_header (mime, "WKS-Phase", "confirm");
+ if (err)
+ goto leave;
+
for (sl = opt.extra_headers; sl; sl = sl->next)
{
err = mime_maker_add_header (mime, sl->d, NULL);
@@ -1008,7 +1020,7 @@ send_confirmation_request (server_ctx_t ctx,
if (err)
goto leave;
- mime_maker_dump_tree (mime);
+ /* mime_maker_dump_tree (mime); */
err = mime_maker_get_part (mime, partid, &signeddata);
if (err)
goto leave;
@@ -1098,7 +1110,7 @@ process_new_key (server_ctx_t ctx, estream_t key)
if (policybuf.auth_submit)
{
- /* Bypass the confirmation stuff and publish the the key as is. */
+ /* Bypass the confirmation stuff and publish the key as is. */
log_info ("publishing address '%s'\n", sl->d);
/* FIXME: We need to make sure that we do this only for the
* address in the mail. */
@@ -1206,6 +1218,13 @@ send_congratulation_message (const char *mbox, const char *keyfile)
err = mime_maker_add_header (mime, "Subject", "Your key has been published");
if (err)
goto leave;
+ err = mime_maker_add_header (mime, "Wks-Draft-Version",
+ STR2(WKS_DRAFT_VERSION));
+ if (err)
+ goto leave;
+ err = mime_maker_add_header (mime, "WKS-Phase", "done");
+ if (err)
+ goto leave;
for (sl = opt.extra_headers; sl; sl = sl->next)
{
err = mime_maker_add_header (mime, sl->d, NULL);
@@ -1515,7 +1534,7 @@ command_receive_cb (void *opaque, const char *mediatype,
/* Return a list of all configured domains. ECh list element is the
- * top directory for for the domain. To figure out the actual domain
+ * top directory for the domain. To figure out the actual domain
* name strrchr(name, '/') can be used. */
static gpg_error_t
get_domain_list (strlist_t *r_list)
diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h
index 62ceb34..3b28af4 100644
--- a/tools/gpg-wks.h
+++ b/tools/gpg-wks.h
@@ -24,6 +24,10 @@
#include "../common/strlist.h"
#include "mime-maker.h"
+/* The draft version we implement. */
+#define WKS_DRAFT_VERSION 3
+
+
/* We keep all global options in the structure OPT. */
struct
{
diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
index a25b513..d53947e 100644
--- a/tools/gpgconf-comp.c
+++ b/tools/gpgconf-comp.c
@@ -47,6 +47,7 @@
#include "util.h"
#include "i18n.h"
#include "exechelp.h"
+#include "sysutils.h"
#include "gc-opt-flags.h"
#include "gpgconf.h"
@@ -716,6 +717,10 @@ static gc_option_t gc_options_gpg[] =
(GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
NULL, NULL,
GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
+ { "trust-model",
+ GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
+ NULL, NULL,
+ GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
{ "Debug",
@@ -743,6 +748,8 @@ static gc_option_t gc_options_gpg[] =
{ "auto-key-locate", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
"gnupg", N_("|MECHANISMS|use MECHANISMS to locate keys by mail address"),
GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
+ { "auto-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
+ NULL, NULL, GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
GC_OPTION_NULL
@@ -2163,8 +2170,11 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
config = es_fopen (config_filename, "r");
if (!config)
- gc_error (0, errno, "warning: can not open config file %s",
- config_filename);
+ {
+ if (errno != ENOENT)
+ gc_error (0, errno, "warning: can not open config file %s",
+ config_filename);
+ }
else
{
while ((length = es_read_line (config, &line, &line_len, NULL)) > 0)
@@ -2265,7 +2275,7 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
gc_option_t *list_option;
gc_option_t *config_option;
char *list_filename;
- FILE *list_file;
+ gpgrt_stream_t list_file;
char *line = NULL;
size_t line_len = 0;
ssize_t length;
@@ -2277,13 +2287,13 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
assert (!list_option->active);
list_filename = get_config_filename (component, backend);
- list_file = fopen (list_filename, "r");
+ list_file = gpgrt_fopen (list_filename, "r");
if (!list_file)
gc_error (0, errno, "warning: can not open list file %s", list_filename);
else
{
- while ((length = read_line (list_file, &line, &line_len, NULL)) > 0)
+ while ((length = gpgrt_read_line (list_file, &line, &line_len, NULL)) > 0)
{
char *start;
char *end;
@@ -2316,7 +2326,7 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
else
list = xasprintf ("\"%s", gc_percent_escape (start));
}
- if (length < 0 || ferror (list_file))
+ if (length < 0 || gpgrt_ferror (list_file))
gc_error (1, errno, "can not read list file %s", list_filename);
}
@@ -2329,7 +2339,7 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
if (config_option->flags & GC_OPT_FLAG_NO_CHANGE)
list_option->flags |= GC_OPT_FLAG_NO_CHANGE;
- if (list_file && fclose (list_file))
+ if (list_file && gpgrt_fclose (list_file))
gc_error (1, errno, "error closing %s", list_filename);
xfree (line);
}
@@ -2515,7 +2525,6 @@ option_check_validity (gc_option_t *option, unsigned long flags,
while (arg && *arg);
}
-
#ifdef HAVE_W32_SYSTEM
int
copy_file (const char *src_name, const char *dst_name)
@@ -2523,18 +2532,18 @@ copy_file (const char *src_name, const char *dst_name)
#define BUF_LEN 4096
char buffer[BUF_LEN];
int len;
- FILE *src;
- FILE *dst;
+ gpgrt_stream_t src;
+ gpgrt_stream_t dst;
- src = fopen (src_name, "r");
+ src = gpgrt_fopen (src_name, "r");
if (src == NULL)
return -1;
- dst = fopen (dst_name, "w");
+ dst = gpgrt_fopen (dst_name, "w");
if (dst == NULL)
{
int saved_err = errno;
- fclose (src);
+ gpgrt_fclose (src);
gpg_err_set_errno (saved_err);
return -1;
}
@@ -2543,28 +2552,28 @@ copy_file (const char *src_name, const char *dst_name)
{
int written;
- len = fread (buffer, 1, BUF_LEN, src);
+ len = gpgrt_fread (buffer, 1, BUF_LEN, src);
if (len == 0)
break;
- written = fwrite (buffer, 1, len, dst);
+ written = gpgrt_fwrite (buffer, 1, len, dst);
if (written != len)
break;
}
- while (!feof (src) && !ferror (src) && !ferror (dst));
+ while (! gpgrt_feof (src) && ! gpgrt_ferror (src) && ! gpgrt_ferror (dst));
- if (ferror (src) || ferror (dst) || !feof (src))
+ if (gpgrt_ferror (src) || gpgrt_ferror (dst) || ! gpgrt_feof (src))
{
int saved_errno = errno;
- fclose (src);
- fclose (dst);
+ gpgrt_fclose (src);
+ gpgrt_fclose (dst);
unlink (dst_name);
gpg_err_set_errno (saved_errno);
return -1;
}
- if (fclose (dst))
+ if (gpgrt_fclose (dst))
gc_error (1, errno, "error closing %s", dst_name);
- if (fclose (src))
+ if (gpgrt_fclose (src))
gc_error (1, errno, "error closing %s", src_name);
return 0;
@@ -2573,7 +2582,20 @@ copy_file (const char *src_name, const char *dst_name)
/* Create and verify the new configuration file for the specified
- backend and component. Returns 0 on success and -1 on error. */
+ * backend and component. Returns 0 on success and -1 on error. This
+ * function may store pointers to malloced strings in SRC_FILENAMEP,
+ * DEST_FILENAMEP, and ORIG_FILENAMEP. Those must be freed by the
+ * caller. The strings refer to three versions of the configuration
+ * file:
+ *
+ * SRC_FILENAME: The updated configuration is written to this file.
+ * DEST_FILENAME: Name of the configuration file read by the
+ * component.
+ * ORIG_FILENAME: A backup of the previous configuration file.
+ *
+ * To apply the configuration change, rename SRC_FILENAME to
+ * DEST_FILENAME. To revert to the previous configuration, rename
+ * ORIG_FILENAME to DEST_FILENAME. */
static int
change_options_file (gc_component_t component, gc_backend_t backend,
char **src_filenamep, char **dest_filenamep,
@@ -2588,8 +2610,8 @@ change_options_file (gc_component_t component, gc_backend_t backend,
ssize_t length;
int res;
int fd;
- FILE *src_file = NULL;
- FILE *dest_file = NULL;
+ gpgrt_stream_t src_file = NULL;
+ gpgrt_stream_t dest_file = NULL;
char *src_filename;
char *dest_filename;
char *orig_filename;
@@ -2641,6 +2663,8 @@ change_options_file (gc_component_t component, gc_backend_t backend,
if (res < 0 && errno != ENOENT)
{
xfree (dest_filename);
+ xfree (src_filename);
+ xfree (orig_filename);
return -1;
}
if (res < 0)
@@ -2659,7 +2683,7 @@ change_options_file (gc_component_t component, gc_backend_t backend,
fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
if (fd < 0)
return -1;
- src_file = fdopen (fd, "w");
+ src_file = gpgrt_fdopen (fd, "w");
res = errno;
if (!src_file)
{
@@ -2673,11 +2697,11 @@ change_options_file (gc_component_t component, gc_backend_t backend,
process. */
if (orig_filename)
{
- dest_file = fopen (dest_filename, "r");
+ dest_file = gpgrt_fopen (dest_filename, "r");
if (!dest_file)
goto change_file_one_err;
- while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
+ while ((length = gpgrt_read_line (dest_file, &line, &line_len, NULL)) > 0)
{
int disable = 0;
char *start;
@@ -2748,24 +2772,24 @@ change_options_file (gc_component_t component, gc_backend_t backend,
{
if (!in_marker)
{
- fprintf (src_file,
+ gpgrt_fprintf (src_file,
"# %s disabled this option here at %s\n",
GPGCONF_DISP_NAME, asctimestamp (gnupg_get_time ()));
- if (ferror (src_file))
+ if (gpgrt_ferror (src_file))
goto change_file_one_err;
- fprintf (src_file, "# %s", line);
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "# %s", line);
+ if (gpgrt_ferror (src_file))
goto change_file_one_err;
}
}
else
{
- fprintf (src_file, "%s", line);
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "%s", line);
+ if (gpgrt_ferror (src_file))
goto change_file_one_err;
}
}
- if (length < 0 || ferror (dest_file))
+ if (length < 0 || gpgrt_ferror (dest_file))
goto change_file_one_err;
}
@@ -2776,8 +2800,8 @@ change_options_file (gc_component_t component, gc_backend_t backend,
proceed. Note that we first write a newline, this guards us
against files which lack the newline at the end of the last
line, while it doesn't hurt us in all other cases. */
- fprintf (src_file, "\n%s\n", marker);
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "\n%s\n", marker);
+ if (gpgrt_ferror (src_file))
goto change_file_one_err;
}
@@ -2787,7 +2811,7 @@ change_options_file (gc_component_t component, gc_backend_t backend,
followed by the rest of the original file. */
while (cur_arg)
{
- fprintf (src_file, "%s\n", cur_arg);
+ gpgrt_fprintf (src_file, "%s\n", cur_arg);
/* Find next argument. */
if (arg)
@@ -2812,52 +2836,52 @@ change_options_file (gc_component_t component, gc_backend_t backend,
cur_arg = NULL;
}
- fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
+ if (gpgrt_ferror (src_file))
goto change_file_one_err;
if (!in_marker)
{
- fprintf (src_file, "# %s edited this configuration file.\n",
+ gpgrt_fprintf (src_file, "# %s edited this configuration file.\n",
GPGCONF_DISP_NAME);
- if (ferror (src_file))
+ if (gpgrt_ferror (src_file))
goto change_file_one_err;
- fprintf (src_file, "# It will disable options before this marked "
+ gpgrt_fprintf (src_file, "# It will disable options before this marked "
"block, but it will\n");
- if (ferror (src_file))
+ if (gpgrt_ferror (src_file))
goto change_file_one_err;
- fprintf (src_file, "# never change anything below these lines.\n");
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "# never change anything below these lines.\n");
+ if (gpgrt_ferror (src_file))
goto change_file_one_err;
}
if (dest_file)
{
- while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
+ while ((length = gpgrt_read_line (dest_file, &line, &line_len, NULL)) > 0)
{
- fprintf (src_file, "%s", line);
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "%s", line);
+ if (gpgrt_ferror (src_file))
goto change_file_one_err;
}
- if (length < 0 || ferror (dest_file))
+ if (length < 0 || gpgrt_ferror (dest_file))
goto change_file_one_err;
}
xfree (line);
line = NULL;
- res = fclose (src_file);
+ res = gpgrt_fclose (src_file);
if (res)
{
res = errno;
close (fd);
if (dest_file)
- fclose (dest_file);
+ gpgrt_fclose (dest_file);
gpg_err_set_errno (res);
return -1;
}
close (fd);
if (dest_file)
{
- res = fclose (dest_file);
+ res = gpgrt_fclose (dest_file);
if (res)
return -1;
}
@@ -2868,11 +2892,11 @@ change_options_file (gc_component_t component, gc_backend_t backend,
res = errno;
if (src_file)
{
- fclose (src_file);
+ gpgrt_fclose (src_file);
close (fd);
}
if (dest_file)
- fclose (dest_file);
+ gpgrt_fclose (dest_file);
gpg_err_set_errno (res);
return -1;
}
@@ -2880,7 +2904,19 @@ change_options_file (gc_component_t component, gc_backend_t backend,
/* Create and verify the new configuration file for the specified
* backend and component. Returns 0 on success and -1 on error. If
- * VERBATIM is set the profile mode is used. */
+ * VERBATIM is set the profile mode is used. This function may store
+ * pointers to malloced strings in SRC_FILENAMEP, DEST_FILENAMEP, and
+ * ORIG_FILENAMEP. Those must be freed by the caller. The strings
+ * refer to three versions of the configuration file:
+ *
+ * SRC_FILENAME: The updated configuration is written to this file.
+ * DEST_FILENAME: Name of the configuration file read by the
+ * component.
+ * ORIG_FILENAME: A backup of the previous configuration file.
+ *
+ * To apply the configuration change, rename SRC_FILENAME to
+ * DEST_FILENAME. To revert to the previous configuration, rename
+ * ORIG_FILENAME to DEST_FILENAME. */
static int
change_options_program (gc_component_t component, gc_backend_t backend,
char **src_filenamep, char **dest_filenamep,
@@ -2896,8 +2932,8 @@ change_options_program (gc_component_t component, gc_backend_t backend,
ssize_t length;
int res;
int fd;
- FILE *src_file = NULL;
- FILE *dest_file = NULL;
+ gpgrt_stream_t src_file = NULL;
+ gpgrt_stream_t dest_file = NULL;
char *src_filename;
char *dest_filename;
char *orig_filename;
@@ -2939,7 +2975,7 @@ change_options_program (gc_component_t component, gc_backend_t backend,
fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
if (fd < 0)
return -1;
- src_file = fdopen (fd, "w");
+ src_file = gpgrt_fdopen (fd, "w");
res = errno;
if (!src_file)
{
@@ -2953,11 +2989,11 @@ change_options_program (gc_component_t component, gc_backend_t backend,
process. */
if (orig_filename)
{
- dest_file = fopen (dest_filename, "r");
+ dest_file = gpgrt_fopen (dest_filename, "r");
if (!dest_file)
goto change_one_err;
- while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
+ while ((length = gpgrt_read_line (dest_file, &line, &line_len, NULL)) > 0)
{
int disable = 0;
char *start;
@@ -3004,24 +3040,24 @@ change_options_program (gc_component_t component, gc_backend_t backend,
{
if (!in_marker)
{
- fprintf (src_file,
+ gpgrt_fprintf (src_file,
"# %s disabled this option here at %s\n",
GPGCONF_DISP_NAME, asctimestamp (gnupg_get_time ()));
- if (ferror (src_file))
+ if (gpgrt_ferror (src_file))
goto change_one_err;
- fprintf (src_file, "# %s", line);
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "# %s", line);
+ if (gpgrt_ferror (src_file))
goto change_one_err;
}
}
else
{
- fprintf (src_file, "%s", line);
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "%s", line);
+ if (gpgrt_ferror (src_file))
goto change_one_err;
}
}
- if (length < 0 || ferror (dest_file))
+ if (length < 0 || gpgrt_ferror (dest_file))
goto change_one_err;
}
@@ -3032,8 +3068,8 @@ change_options_program (gc_component_t component, gc_backend_t backend,
proceed. Note that we first write a newline, this guards us
against files which lack the newline at the end of the last
line, while it doesn't hurt us in all other cases. */
- fprintf (src_file, "\n%s\n", marker);
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "\n%s\n", marker);
+ if (gpgrt_ferror (src_file))
goto change_one_err;
}
/* At this point, we have copied everything up to the end marker
@@ -3044,7 +3080,7 @@ change_options_program (gc_component_t component, gc_backend_t backend,
/* We have to turn on UTF8 strings for GnuPG. */
if (backend == GC_BACKEND_GPG && ! utf8strings_seen)
- fprintf (src_file, "utf8-strings\n");
+ gpgrt_fprintf (src_file, "utf8-strings\n");
option = gc_component[component].options;
while (option->name)
@@ -3059,16 +3095,16 @@ change_options_program (gc_component_t component, gc_backend_t backend,
{
if (*arg == '\0' || *arg == ',')
{
- fprintf (src_file, "%s\n", option->name);
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "%s\n", option->name);
+ if (gpgrt_ferror (src_file))
goto change_one_err;
}
else if (gc_arg_type[option->arg_type].fallback
== GC_ARG_TYPE_NONE)
{
assert (*arg == '1');
- fprintf (src_file, "%s\n", option->name);
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "%s\n", option->name);
+ if (gpgrt_ferror (src_file))
goto change_one_err;
arg++;
@@ -3090,9 +3126,9 @@ change_options_program (gc_component_t component, gc_backend_t backend,
else
end = NULL;
- fprintf (src_file, "%s %s\n", option->name,
+ gpgrt_fprintf (src_file, "%s %s\n", option->name,
verbatim? arg : percent_deescape (arg));
- if (ferror (src_file))
+ if (gpgrt_ferror (src_file))
goto change_one_err;
if (end)
@@ -3107,8 +3143,8 @@ change_options_program (gc_component_t component, gc_backend_t backend,
if (end)
*end = '\0';
- fprintf (src_file, "%s %s\n", option->name, arg);
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "%s %s\n", option->name, arg);
+ if (gpgrt_ferror (src_file))
goto change_one_err;
if (end)
@@ -3125,52 +3161,52 @@ change_options_program (gc_component_t component, gc_backend_t backend,
option++;
}
- fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
+ if (gpgrt_ferror (src_file))
goto change_one_err;
if (!in_marker)
{
- fprintf (src_file, "# %s edited this configuration file.\n",
+ gpgrt_fprintf (src_file, "# %s edited this configuration file.\n",
GPGCONF_DISP_NAME);
- if (ferror (src_file))
+ if (gpgrt_ferror (src_file))
goto change_one_err;
- fprintf (src_file, "# It will disable options before this marked "
+ gpgrt_fprintf (src_file, "# It will disable options before this marked "
"block, but it will\n");
- if (ferror (src_file))
+ if (gpgrt_ferror (src_file))
goto change_one_err;
- fprintf (src_file, "# never change anything below these lines.\n");
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "# never change anything below these lines.\n");
+ if (gpgrt_ferror (src_file))
goto change_one_err;
}
if (dest_file)
{
- while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
+ while ((length = gpgrt_read_line (dest_file, &line, &line_len, NULL)) > 0)
{
- fprintf (src_file, "%s", line);
- if (ferror (src_file))
+ gpgrt_fprintf (src_file, "%s", line);
+ if (gpgrt_ferror (src_file))
goto change_one_err;
}
- if (length < 0 || ferror (dest_file))
+ if (length < 0 || gpgrt_ferror (dest_file))
goto change_one_err;
}
xfree (line);
line = NULL;
- res = fclose (src_file);
+ res = gpgrt_fclose (src_file);
if (res)
{
res = errno;
close (fd);
if (dest_file)
- fclose (dest_file);
+ gpgrt_fclose (dest_file);
gpg_err_set_errno (res);
return -1;
}
close (fd);
if (dest_file)
{
- res = fclose (dest_file);
+ res = gpgrt_fclose (dest_file);
if (res)
return -1;
}
@@ -3181,11 +3217,11 @@ change_options_program (gc_component_t component, gc_backend_t backend,
res = errno;
if (src_file)
{
- fclose (src_file);
+ gpgrt_fclose (src_file);
close (fd);
}
if (dest_file)
- fclose (dest_file);
+ gpgrt_fclose (dest_file);
gpg_err_set_errno (res);
return -1;
}
@@ -3240,6 +3276,7 @@ gc_component_change_options (int component, estream_t in, estream_t out,
int verbatim)
{
int err = 0;
+ int block = 0;
int runtime[GC_BACKEND_NR];
char *src_filename[GC_BACKEND_NR];
char *dest_filename[GC_BACKEND_NR];
@@ -3326,6 +3363,8 @@ gc_component_change_options (int component, estream_t in, estream_t out,
change_one_value (option, runtime, flags, new_value, 0);
}
+ if (length < 0 || gpgrt_ferror (in))
+ gc_error (1, errno, "error reading stream 'in'");
}
/* Now that we have collected and locally verified the changes,
@@ -3377,6 +3416,14 @@ gc_component_change_options (int component, estream_t in, estream_t out,
option++;
}
+ /* We are trying to atomically commit all changes. Unfortunately,
+ we cannot rely on gnupg_rename_file to manage the signals for us,
+ doing so would require us to pass NULL as BLOCK to any subsequent
+ call to it. Instead, we just manage the signal handling
+ manually. */
+ block = 1;
+ gnupg_block_all_signals ();
+
if (! err && ! opt.dry_run)
{
int i;
@@ -3390,20 +3437,13 @@ gc_component_change_options (int component, estream_t in, estream_t out,
assert (dest_filename[i]);
if (orig_filename[i])
- {
-#ifdef HAVE_W32_SYSTEM
- /* There is no atomic update on W32. */
- err = unlink (dest_filename[i]);
-#endif /* HAVE_W32_SYSTEM */
- if (!err)
- err = rename (src_filename[i], dest_filename[i]);
- }
+ err = gnupg_rename_file (src_filename[i], dest_filename[i], NULL);
else
{
#ifdef HAVE_W32_SYSTEM
/* We skip the unlink if we expect the file not to
be there. */
- err = rename (src_filename[i], dest_filename[i]);
+ err = gnupg_rename_file (src_filename[i], dest_filename[i], NULL);
#else /* HAVE_W32_SYSTEM */
/* This is a bit safer than rename() because we
expect DEST_FILENAME not to be there. If it
@@ -3443,13 +3483,7 @@ gc_component_change_options (int component, estream_t in, estream_t out,
a version of the file that is even newer than the one
we just installed. */
if (orig_filename[i])
- {
-#ifdef HAVE_W32_SYSTEM
- /* There is no atomic update on W32. */
- unlink (dest_filename[i]);
-#endif /* HAVE_W32_SYSTEM */
- rename (orig_filename[i], dest_filename[i]);
- }
+ gnupg_rename_file (orig_filename[i], dest_filename[i], NULL);
else
unlink (dest_filename[i]);
}
@@ -3479,16 +3513,13 @@ gc_component_change_options (int component, estream_t in, estream_t out,
backup_filename = xasprintf ("%s.%s.bak",
dest_filename[backend], GPGCONF_NAME);
-
-#ifdef HAVE_W32_SYSTEM
- /* There is no atomic update on W32. */
- unlink (backup_filename);
-#endif /* HAVE_W32_SYSTEM */
- rename (orig_filename[backend], backup_filename);
+ gnupg_rename_file (orig_filename[backend], backup_filename, NULL);
xfree (backup_filename);
}
leave:
+ if (block)
+ gnupg_unblock_all_signals ();
xfree (line);
for (backend = 0; backend < GC_BACKEND_NR; backend++)
{
@@ -3623,7 +3654,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
char *line = NULL;
size_t line_len = 0;
ssize_t length;
- FILE *config;
+ gpgrt_stream_t config;
int lineno = 0;
int in_rule = 0;
int got_match = 0;
@@ -3640,7 +3671,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
runtime[backend_id] = 0;
- config = fopen (fname, "r");
+ config = gpgrt_fopen (fname, "r");
if (!config)
{
/* Do not print an error if the file is not available, except
@@ -3654,7 +3685,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
return result;
}
- while ((length = read_line (config, &line, &line_len, NULL)) > 0)
+ while ((length = gpgrt_read_line (config, &line, &line_len, NULL)) > 0)
{
char *key, *component, *option, *flags, *value;
char *empty;
@@ -3880,12 +3911,12 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
}
}
- if (length < 0 || ferror (config))
+ if (length < 0 || gpgrt_ferror (config))
{
gc_error (0, errno, "error reading from '%s'", fname);
result = -1;
}
- if (fclose (config))
+ if (gpgrt_fclose (config))
gc_error (0, errno, "error closing '%s'", fname);
xfree (line);
diff --git a/tools/gpgconf.c b/tools/gpgconf.c
index a5ee188..a9f4607 100644
--- a/tools/gpgconf.c
+++ b/tools/gpgconf.c
@@ -109,7 +109,7 @@ static ARGPARSE_OPTS opts[] =
};
-/* Print usage information and and provide strings for help. */
+/* Print usage information and provide strings for help. */
static const char *
my_strusage( int level )
{
diff --git a/tools/gpgparsemail.c b/tools/gpgparsemail.c
index 8c9c4d4..b122097 100644
--- a/tools/gpgparsemail.c
+++ b/tools/gpgparsemail.c
@@ -463,7 +463,7 @@ show_event (rfc822parse_event_t event)
/* This function is called by the parser to communicate events. This
callback comminucates with the main program using a structure
- passed in OPAQUE. Should retrun 0 or set errno and return -1. */
+ passed in OPAQUE. Should return 0 or set errno and return -1. */
static int
message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
{
diff --git a/tools/gpgtar.c b/tools/gpgtar.c
index 23176dc..3dff176 100644
--- a/tools/gpgtar.c
+++ b/tools/gpgtar.c
@@ -137,7 +137,7 @@ static ARGPARSE_OPTS tar_opts[] = {
-/* Print usage information and and provide strings for help. */
+/* Print usage information and provide strings for help. */
static const char *
my_strusage( int level )
{
@@ -507,7 +507,7 @@ main (int argc, char **argv)
/* Read the next record from STREAM. RECORD is a buffer provided by
the caller and must be at leadt of size RECORDSIZE. The function
- return 0 on success and and error code on failure; a diagnostic
+ return 0 on success and error code on failure; a diagnostic
printed as well. Note that there is no need for an EOF indicator
because a tarball has an explicit EOF record. */
gpg_error_t
diff --git a/tools/mail-signed-keys b/tools/mail-signed-keys
index c63001a..3c564f1 100755
--- a/tools/mail-signed-keys
+++ b/tools/mail-signed-keys
@@ -41,7 +41,7 @@ if [ -z "$signedby" ]; then
fi
if [ "$dryrun" = "0" ]; then
- echo "About to send the the keys signed by $signedby" >&2
+ echo "About to send the keys signed by $signedby" >&2
echo -n "to their owners. Do you really want to do this? (y/N)" >&2
read
[ "$REPLY" != "y" -a "$REPLY" != "Y" ] && exit 0
diff --git a/tools/mime-parser.c b/tools/mime-parser.c
index 264353c..169ea2b 100644
--- a/tools/mime-parser.c
+++ b/tools/mime-parser.c
@@ -49,6 +49,9 @@ struct mime_parser_context_s
{
void *cookie; /* Cookie passed to all callbacks. */
+ /* The callback to announce the transation from header to body. */
+ gpg_error_t (*t2body) (void *cookie, int level);
+
/* The callback to announce a new part. */
gpg_error_t (*new_part) (void *cookie,
const char *mediatype,
@@ -224,6 +227,14 @@ parse_message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
ctx->want_part = 0;
ctx->decode_part = 0;
+
+ if (ctx->t2body)
+ {
+ rc = ctx->t2body (ctx->cookie, ctx->nesting_level);
+ if (rc)
+ goto t2body_leave;
+ }
+
field = rfc822parse_parse_field (msg, "Content-Type", -1);
if (field)
{
@@ -412,6 +423,7 @@ parse_message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
}
}
+ t2body_leave:
ctx->show.header = 0;
ctx->show.data = 1;
ctx->show.n_skip = 1;
@@ -541,6 +553,19 @@ mime_parser_set_verbose (mime_parser_t ctx, int level)
}
+/* Set a callback for the transition from header to body. LEVEL is
+ * the current nesting level, starting with 0. This callback can be
+ * used to evaluate headers before any other action is done. Note
+ * that if a new NEW_PART callback needs to be called it is done after
+ * this T2BODY callback. */
+void
+mime_parser_set_t2body (mime_parser_t ctx,
+ gpg_error_t (*fnc) (void *cookie, int level))
+{
+ ctx->t2body = fnc;
+}
+
+
/* Set the callback used to announce a new part. It will be called
* with the media type and media subtype of the part. If no
* Content-type header was given both values are the empty string.
diff --git a/tools/mime-parser.h b/tools/mime-parser.h
index 37a74a1..b9bb465 100644
--- a/tools/mime-parser.h
+++ b/tools/mime-parser.h
@@ -27,6 +27,8 @@ gpg_error_t mime_parser_new (mime_parser_t *r_ctx, void *cookie);
void mime_parser_release (mime_parser_t ctx);
void mime_parser_set_verbose (mime_parser_t ctx, int level);
+void mime_parser_set_t2body (mime_parser_t ctx,
+ gpg_error_t (*fnc) (void *cookie, int level));
void mime_parser_set_new_part (mime_parser_t ctx,
gpg_error_t (*fnc) (void *cookie,
const char *mediatype,
diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c
index dc680f5..a72b9cf 100644
--- a/tools/symcryptrun.c
+++ b/tools/symcryptrun.c
@@ -191,7 +191,7 @@ struct
} opt;
-/* Print usage information and and provide strings for help. */
+/* Print usage information and provide strings for help. */
static const char *
my_strusage (int level)
{
@@ -997,7 +997,7 @@ main (int argc, char **argv)
setup_libgcrypt_logging ();
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
- /* Tell simple-pwquery about the the standard socket name. */
+ /* Tell simple-pwquery about the standard socket name. */
{
char *tmp = make_filename (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
simple_pw_set_socket (tmp);
diff --git a/tools/wks-receive.c b/tools/wks-receive.c
index 12ec089..94f8bc6 100644
--- a/tools/wks-receive.c
+++ b/tools/wks-receive.c
@@ -255,6 +255,38 @@ collect_signature (void *cookie, const char *data)
}
+/* The callback for the transition from header to body. We use it to
+ * look at some header values. */
+static gpg_error_t
+t2body (void *cookie, int level)
+{
+ receive_ctx_t ctx = cookie;
+ rfc822parse_t msg;
+ char *value;
+ size_t valueoff;
+
+ log_info ("t2body for level %d\n", level);
+ if (!level)
+ {
+ /* This is the outermost header. */
+ msg = mime_parser_rfc822parser (ctx->parser);
+ if (msg)
+ {
+ value = rfc822parse_get_field (msg, "Wks-Draft-Version",
+ -1, &valueoff);
+ if (value)
+ {
+ if (atoi(value+valueoff) >= 2 )
+ ctx->draft_version_2 = 1;
+ free (value);
+ }
+ }
+ }
+
+ return 0;
+}
+
+
static gpg_error_t
new_part (void *cookie, const char *mediatype, const char *mediasubtype)
{
@@ -275,22 +307,6 @@ new_part (void *cookie, const char *mediatype, const char *mediasubtype)
}
else
{
- rfc822parse_t msg = mime_parser_rfc822parser (ctx->parser);
- if (msg)
- {
- char *value;
- size_t valueoff;
-
- value = rfc822parse_get_field (msg, "Wks-Draft-Version",
- -1, &valueoff);
- if (value)
- {
- if (atoi(value+valueoff) >= 2 )
- ctx->draft_version_2 = 1;
- free (value);
- }
- }
-
ctx->key_data = es_fopenmem (0, "w+b");
if (!ctx->key_data)
{
@@ -413,6 +429,7 @@ wks_receive (estream_t fp,
goto leave;
if (DBG_PARSER)
mime_parser_set_verbose (parser, 1);
+ mime_parser_set_t2body (parser, t2body);
mime_parser_set_new_part (parser, new_part);
mime_parser_set_part_data (parser, part_data);
mime_parser_set_collect_encrypted (parser, collect_encrypted);