From 163e4ff1959788781403ddf85f808054de414fd6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 10 Nov 2020 12:09:11 +0100 Subject: [PATCH] w32: Support Unicode also for config files etc. * common/sysutils.c (gnupg_fopen) [W32]: Use _wfopen if needed. Use new function in most places where fopen is used. -- The config files in 2.2 are still read using fopen - we need to change this to allow Unicode directory names. There is also one case where files are written using the old fopen. The new option parser in 2.3 does not have this problem but at some places fopen is also still used. GnuPG-bug-id: 5098 Signed-off-by: Werner Koch --- agent/gpg-agent.c | 4 ++-- agent/protect-tool.c | 2 +- common/sysutils.c | 49 +++++++++++++++++++++++++++++++++++++++ common/util.h | 4 +++- dirmngr/dirmngr-client.c | 4 ++-- dirmngr/dirmngr.c | 4 ++-- g10/exec.c | 2 +- g10/gpg.c | 2 +- g10/keydb.c | 2 +- g10/plaintext.c | 2 +- g13/g13-syshelp.c | 2 +- g13/g13.c | 2 +- kbx/kbxutil.c | 2 +- scd/scdaemon.c | 2 +- sm/gpgsm.c | 2 +- sm/minip12.c | 2 +- tools/gpg-connect-agent.c | 2 +- tools/gpgparsemail.c | 2 +- tools/gpgsplit.c | 4 ++-- tools/symcryptrun.c | 6 ++--- 20 files changed, 76 insertions(+), 25 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 22f8b9439..795f28206 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1154,7 +1154,7 @@ main (int argc, char **argv ) if (configname) { configlineno = 0; - configfp = fopen (configname, "r"); + configfp = gnupg_fopen (configname, "r"); if (!configfp) { if (default_config) @@ -2026,7 +2026,7 @@ reread_configuration (void) if (!config_filename) return; /* No config file. */ - fp = fopen (config_filename, "r"); + fp = gnupg_fopen (config_filename, "r"); if (!fp) { log_info (_("option file '%s': %s\n"), diff --git a/agent/protect-tool.c b/agent/protect-tool.c index 0ba31c1a0..f55a7354d 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -275,7 +275,7 @@ read_file (const char *fname, size_t *r_length) { struct stat st; - fp = fopen (fname, "rb"); + fp = gnupg_fopen (fname, "rb"); if (!fp) { log_error ("can't open '%s': %s\n", fname, strerror (errno)); diff --git a/common/sysutils.c b/common/sysutils.c index df62aa254..520aa56e4 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -1219,6 +1219,55 @@ gnupg_stat (const char *name, struct stat *statbuf) #endif /*HAVE_STAT*/ +/* Wrapper around fopen for the cases where we have not yet switched + * to es_fopen. Note that for convenience the prototype is in util.h */ +FILE * +gnupg_fopen (const char *fname, const char *mode) +{ +#ifdef HAVE_W32_SYSTEM + if (any8bitchar (fname)) + { + wchar_t *wfname; + const wchar_t *wmode; + wchar_t *wmodebuf = NULL; + FILE *ret; + + wfname = utf8_to_wchar (fname); + if (!wfname) + return NULL; + if (!strcmp (mode, "r")) + wmode = L"r"; + else if (!strcmp (mode, "rb")) + wmode = L"rb"; + else if (!strcmp (mode, "w")) + wmode = L"w"; + else if (!strcmp (mode, "wb")) + wmode = L"wb"; + else + { + wmodebuf = utf8_to_wchar (mode); + if (!wmodebuf) + { + xfree (wfname); + return NULL; + } + wmode = wmodebuf; + } + ret = _wfopen (wfname, wmode); + xfree (wfname); + xfree (wmodebuf); + return ret; + } + else + return fopen (fname, mode); + +#else /*Unix*/ + return fopen (fname, mode); +#endif /*Unix*/ +} + + + /* A wrapper around open to handle Unicode file names under Windows. */ int gnupg_open (const char *name, int flags, unsigned int mode) diff --git a/common/util.h b/common/util.h index 4d61bc0ea..75cdee0b4 100644 --- a/common/util.h +++ b/common/util.h @@ -142,7 +142,6 @@ ssize_t read_line (FILE *fp, char **addr_of_buffer, size_t *length_of_buffer, size_t *max_length); - /*-- b64enc.c and b64dec.c --*/ struct b64state { @@ -287,6 +286,9 @@ char *gnupg_get_help_string (const char *key, int only_current_locale); /*-- localename.c --*/ const char *gnupg_messages_locale_name (void); +/*-- sysutils.c --*/ +FILE *gnupg_fopen (const char *fname, const char *mode); + /*-- miscellaneous.c --*/ /* This function is called at startup to tell libgcrypt to use our own diff --git a/dirmngr/dirmngr-client.c b/dirmngr/dirmngr-client.c index 53b405ea2..0d714d485 100644 --- a/dirmngr/dirmngr-client.c +++ b/dirmngr/dirmngr-client.c @@ -468,7 +468,7 @@ read_pem_certificate (const char *fname, unsigned char **rbuf, size_t *rbuflen) init_asctobin (); - fp = fname? fopen (fname, "r") : stdin; + fp = fname? gnupg_fopen (fname, "r") : stdin; if (!fp) return gpg_error_from_errno (errno); @@ -629,7 +629,7 @@ read_certificate (const char *fname, unsigned char **rbuf, size_t *rbuflen) return 0; } - fp = fname? fopen (fname, "rb") : stdin; + fp = fname? gnupg_fopen (fname, "rb") : stdin; if (!fp) return gpg_error_from_errno (errno); diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 3500e7eea..e497183c1 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -947,7 +947,7 @@ main (int argc, char **argv) if (configname) { configlineno = 0; - configfp = fopen (configname, "r"); + configfp = gnupg_fopen (configname, "r"); if (!configfp) { if (default_config) @@ -1840,7 +1840,7 @@ reread_configuration (void) if (!opt.config_filename) return; /* No config file. */ - fp = fopen (opt.config_filename, "r"); + fp = gnupg_fopen (opt.config_filename, "r"); if (!fp) { log_error (_("option file '%s': %s\n"), diff --git a/g10/exec.c b/g10/exec.c index 3e5dc278b..1baa49f02 100644 --- a/g10/exec.c +++ b/g10/exec.c @@ -539,7 +539,7 @@ exec_write(struct exec_info **info,const char *program, gpg_err_set_errno (EPERM); } else - (*info)->tochild=fopen((*info)->tempfile_in,binary?"wb":"w"); + (*info)->tochild = gnupg_fopen ((*info)->tempfile_in,binary?"wb":"w"); if((*info)->tochild==NULL) { ret = gpg_error_from_syserror (); diff --git a/g10/gpg.c b/g10/gpg.c index bb72b8122..a3ada64c8 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2536,7 +2536,7 @@ main (int argc, char **argv) } configlineno = 0; - configfp = fopen( configname, "r" ); + configfp = gnupg_fopen( configname, "r" ); if (configfp && is_secured_file (fileno (configfp))) { fclose (configfp); diff --git a/g10/keydb.c b/g10/keydb.c index 9798b5cde..e538fe458 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -504,7 +504,7 @@ rt_from_file (const char *filename, int *r_found, int *r_openpgp) KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; *r_found = *r_openpgp = 0; - fp = fopen (filename, "rb"); + fp = gnupg_fopen (filename, "rb"); if (fp) { *r_found = 1; diff --git a/g10/plaintext.c b/g10/plaintext.c index f9e0a4296..3bc86968b 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -185,7 +185,7 @@ get_output_file (const byte *embedded_name, int embedded_namelen, want to port it again to riscos we should do most of the suff in estream. FIXME: Consider to remove all riscos special cases. */ - fp = fopen (fname, "wb"); + fp = gnupg_fopen (fname, "wb"); if (!fp) { log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err)); diff --git a/g13/g13-syshelp.c b/g13/g13-syshelp.c index ae603e1d2..e6755d575 100644 --- a/g13/g13-syshelp.c +++ b/g13/g13-syshelp.c @@ -325,7 +325,7 @@ main ( int argc, char **argv) if (configname) { configlineno = 0; - configfp = fopen (configname, "r"); + configfp = gnupg_fopen (configname, "r"); if (!configfp) { if (default_config) diff --git a/g13/g13.c b/g13/g13.c index 6265b9f24..c4cd34b2a 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -454,7 +454,7 @@ main ( int argc, char **argv) if (configname) { configlineno = 0; - configfp = fopen (configname, "r"); + configfp = gnupg_fopen (configname, "r"); if (!configfp) { if (default_config) diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index 6fb05ff6c..ec5a43b5d 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -272,7 +272,7 @@ read_file (const char *fname, size_t *r_length) { struct stat st; - fp = fopen (fname, "rb"); + fp = gnupg_fopen (fname, "rb"); if (!fp) { log_error ("can't open '%s': %s\n", fname, strerror (errno)); diff --git a/scd/scdaemon.c b/scd/scdaemon.c index ab3e1d94a..c1a3f438b 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -524,7 +524,7 @@ main (int argc, char **argv ) if (configname) { configlineno = 0; - configfp = fopen (configname, "r"); + configfp = gnupg_fopen (configname, "r"); if (!configfp) { if (default_config) diff --git a/sm/gpgsm.c b/sm/gpgsm.c index eca266c8e..321826145 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1037,7 +1037,7 @@ main ( int argc, char **argv) next_pass: if (configname) { configlineno = 0; - configfp = fopen (configname, "r"); + configfp = gnupg_fopen (configname, "r"); if (!configfp) { if (default_config) diff --git a/sm/minip12.c b/sm/minip12.c index f066892a0..7087e444c 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -2565,7 +2565,7 @@ main (int argc, char **argv) gcry_control (GCRYCTL_DISABLE_SECMEM, NULL); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL); - fp = fopen (argv[1], "rb"); + fp = gnupg_fopen (argv[1], "rb"); if (!fp) { fprintf (stderr, "can't open '%s': %s\n", argv[1], strerror (errno)); diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index a06d6fd2c..0dabdad16 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -1967,7 +1967,7 @@ handle_inquire (assuan_context_t ctx, char *line) } else { - fp = fopen (d->file, "rb"); + fp = gnupg_fopen (d->file, "rb"); if (!fp) log_error ("error opening '%s': %s\n", d->file, strerror (errno)); else if (opt.verbose) diff --git a/tools/gpgparsemail.c b/tools/gpgparsemail.c index b12209755..f54f1d46a 100644 --- a/tools/gpgparsemail.c +++ b/tools/gpgparsemail.c @@ -796,7 +796,7 @@ main (int argc, char **argv) if (argc && strcmp (*argv, "-")) { - FILE *fp = fopen (*argv, "rb"); + FILE *fp = gnupg_fopen (*argv, "rb"); if (!fp) die ("can't open '%s': %s", *argv, strerror (errno)); parse_message (fp); diff --git a/tools/gpgsplit.c b/tools/gpgsplit.c index 674be6271..e84400854 100644 --- a/tools/gpgsplit.c +++ b/tools/gpgsplit.c @@ -552,7 +552,7 @@ write_part (FILE *fpin, unsigned long pktlen, { if (opt_verbose) log_info ("writing '%s'\n", outname); - fpout = fopen (outname, "wb"); + fpout = gnupg_fopen (outname, "wb"); if (!fpout) { log_error ("error creating '%s': %s\n", outname, strerror(errno)); @@ -873,7 +873,7 @@ split_packets (const char *fname) fp = stdin; fname = "-"; } - else if ( !(fp = fopen (fname,"rb")) ) + else if ( !(fp = gnupg_fopen (fname,"rb")) ) { log_error ("can't open '%s': %s\n", fname, strerror (errno)); return; diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c index c5780fdf5..d1f953c9c 100644 --- a/tools/symcryptrun.c +++ b/tools/symcryptrun.c @@ -363,7 +363,7 @@ confucius_copy_file (char *infile, char *outfile, int plain) } else { - in = fopen (infile, "rb"); + in = gnupg_fopen (infile, "rb"); if (!in) { log_error (_("could not open %s for writing: %s\n"), @@ -380,7 +380,7 @@ confucius_copy_file (char *infile, char *outfile, int plain) } else { - out = fopen (outfile, "wb"); + out = gnupg_fopen (outfile, "wb"); if (!out) { log_error (_("could not open %s for writing: %s\n"), @@ -936,7 +936,7 @@ main (int argc, char **argv) if (configname) { configlineno = 0; - configfp = fopen (configname, "r"); + configfp = gnupg_fopen (configname, "r"); if (!configfp) { if (!default_config)