summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2020-10-20 10:43:55 +0200
committerWerner Koch <wk@gnupg.org>2020-10-20 12:15:55 +0200
commitc94ee1386e0d5cdac51086c4d5b92de59c09c9b5 (patch)
tree34089b99da850a449f95ab9dd7e88317194b5f11 /common
parentgpg,ecc: Fix SOS handling when receiving from agent. (diff)
downloadgnupg2-c94ee1386e0d5cdac51086c4d5b92de59c09c9b5.tar.xz
gnupg2-c94ee1386e0d5cdac51086c4d5b92de59c09c9b5.zip
Replace all calls to access by gnupg_access
* common/sysutils.c (gnupg_access): New. Replace all calls to access by this wrapper. * common/homedir.c (w32_shgetfolderpath): Change to return UTF-8 directory name. (standard_homedir): Adjust for change. (w32_commondir, gnupg_cachedir): Ditto. -- Also use SHGetFolderPathW instead of SHGetFolderPathA on Windows. This is required to correctly handle non-ascii filenames on Windows. GnuPG-bug-id: 5098
Diffstat (limited to 'common')
-rw-r--r--common/exechelp-posix.c5
-rw-r--r--common/exechelp-w32.c5
-rw-r--r--common/homedir.c77
-rw-r--r--common/sysutils.c43
-rw-r--r--common/sysutils.h1
-rw-r--r--common/t-exectool.c1
6 files changed, 69 insertions, 63 deletions
diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c
index 2b724ce5f..b14410821 100644
--- a/common/exechelp-posix.c
+++ b/common/exechelp-posix.c
@@ -845,14 +845,15 @@ gpg_error_t
gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
const char *envp[] )
{
+ gpg_err_code_t ec;
pid_t pid;
int i;
if (getuid() != geteuid())
return my_error (GPG_ERR_BUG);
- if (access (pgmname, X_OK))
- return my_error_from_syserror ();
+ if ((ec = gnupg_access (pgmname, X_OK)))
+ return gpg_err_make (default_errsource, ec);
pid = fork ();
if (pid == (pid_t)(-1))
diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c
index be684caaa..a7897cbfc 100644
--- a/common/exechelp-w32.c
+++ b/common/exechelp-w32.c
@@ -866,13 +866,14 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
int cr_flags;
char *cmdline;
BOOL in_job = FALSE;
+ gpg_err_code_t ec;
/* We don't use ENVP. */
(void)envp;
- if (access (pgmname, X_OK))
- return my_error_from_syserror ();
+ if ((ec = gnupg_access (pgmname, X_OK)))
+ return gpg_err_make (default_errsource, ec);
/* Prepare security attributes. */
memset (&sec_attr, 0, sizeof sec_attr );
diff --git a/common/homedir.c b/common/homedir.c
index f0e5362ba..dd1575cd0 100644
--- a/common/homedir.c
+++ b/common/homedir.c
@@ -117,14 +117,16 @@ w32_try_mkdir (const char *dir)
#endif
-/* This is a helper function to load a Windows function from either of
- one DLLs. */
+/* This is a helper function to load and call a Windows function from
+ * either of one DLLs. On success an UTF-8 file name is returned.
+ * ERRNO is _not_ set on error. */
#ifdef HAVE_W32_SYSTEM
-static HRESULT
-w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
+static char *
+w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d)
{
static int initialized;
- static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
+ static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPWSTR);
+ wchar_t wfname[MAX_PATH];
if (!initialized)
{
@@ -139,7 +141,7 @@ w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
handle = dlopen (dllnames[i], RTLD_LAZY);
if (handle)
{
- func = dlsym (handle, "SHGetFolderPathA");
+ func = dlsym (handle, "SHGetFolderPathW");
if (!func)
{
dlclose (handle);
@@ -149,10 +151,10 @@ w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
}
}
- if (func)
- return func (a,b,c,d,e);
+ if (func && func (a,b,c,d,wfname) >= 0)
+ return wchar_to_utf8 (wfname);
else
- return -1;
+ return NULL;
}
#endif /*HAVE_W32_SYSTEM*/
@@ -248,25 +250,17 @@ standard_homedir (void)
}
else
{
- char path[MAX_PATH];
-
- /* It might be better to use LOCAL_APPDATA because this is
- defined as "non roaming" and thus more likely to be kept
- locally. For private keys this is desired. However,
- given that many users copy private keys anyway forth and
- back, using a system roaming services might be better
- than to let them do it manually. A security conscious
- user will anyway use the registry entry to have better
- control. */
- if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
- NULL, 0, path) >= 0)
+ char *path;
+
+ path = w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
+ NULL, 0);
+ if (path)
{
- char *tmp = xmalloc (strlen (path) + 6 +1);
- strcpy (stpcpy (tmp, path), "\\gnupg");
- dir = tmp;
+ dir = xstrconcat (path, "\\gnupg", NULL);
+ xfree (path);
/* Try to create the directory if it does not yet exists. */
- if (access (dir, F_OK))
+ if (gnupg_access (dir, F_OK))
w32_try_mkdir (dir);
}
else
@@ -360,10 +354,10 @@ check_portable_app (const char *dir)
char *fname;
fname = xstrconcat (dir, DIRSEP_S "gpgconf.exe", NULL);
- if (!access (fname, F_OK))
+ if (!gnupg_access (fname, F_OK))
{
strcpy (fname + strlen (fname) - 3, "ctl");
- if (!access (fname, F_OK))
+ if (!gnupg_access (fname, F_OK))
{
/* gpgconf.ctl file found. Record this fact. */
w32_portable_app = 1;
@@ -440,7 +434,7 @@ w32_commondir (void)
if (!dir)
{
const char *rdir;
- char path[MAX_PATH];
+ char *path;
/* Make sure that w32_rootdir has been called so that we are
able to check the portable application flag. The common dir
@@ -450,19 +444,17 @@ w32_commondir (void)
if (w32_portable_app)
return rdir;
- if (w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA,
- NULL, 0, path) >= 0)
+ path = w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA, NULL, 0);
+ if (path)
{
- char *tmp = xmalloc (strlen (path) + 4 +1);
- strcpy (stpcpy (tmp, path), "\\GNU");
- dir = tmp;
+ dir = xstrconcat (path, "\\GNU", NULL);
/* No auto create of the directory. Either the installer or
- the admin has to create these directories. */
+ * the admin has to create these directories. */
}
else
{
- /* Ooops: Not defined - probably an old Windows version.
- Use the installation directory instead. */
+ /* Folder not found or defined - probably an old Windows
+ * version. Use the installation directory instead. */
dir = xstrdup (rdir);
}
}
@@ -903,7 +895,7 @@ gnupg_cachedir (void)
}
else
{
- char path[MAX_PATH];
+ char *path;
const char *s1[] = { "GNU", "cache", "gnupg", NULL };
int s1_len;
const char **comp;
@@ -912,8 +904,10 @@ gnupg_cachedir (void)
for (comp = s1; *comp; comp++)
s1_len += 1 + strlen (*comp);
- if (w32_shgetfolderpath (NULL, CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE,
- NULL, 0, path) >= 0)
+ path = w32_shgetfolderpath (NULL,
+ CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE,
+ NULL, 0);
+ if (path)
{
char *tmp = xmalloc (strlen (path) + s1_len + 1);
char *p;
@@ -924,11 +918,12 @@ gnupg_cachedir (void)
p = stpcpy (p, "\\");
p = stpcpy (p, *comp);
- if (access (tmp, F_OK))
+ if (gnupg_access (tmp, F_OK))
w32_try_mkdir (tmp);
}
dir = tmp;
+ xfree (path);
}
else
{
@@ -1025,7 +1020,7 @@ get_default_pinentry_name (int reset)
char *name2;
name2 = xstrconcat (names[i].rfnc (), names[i].name, NULL);
- if (!access (name2, F_OK))
+ if (!gnupg_access (name2, F_OK))
{
/* Use that pinentry. */
xfree (name);
diff --git a/common/sysutils.c b/common/sysutils.c
index 140d1d7be..99bc021f5 100644
--- a/common/sysutils.c
+++ b/common/sysutils.c
@@ -811,7 +811,7 @@ gnupg_mkdir (const char *name, const char *modestr)
int
gnupg_chdir (const char *name)
{
- /* Note that gpgrt_chdir also sets ERRNO in addition to returing an
+ /* Note that gpgrt_chdir also sets ERRNO in addition to returning an
* gpg-error style error code. */
return gpgrt_chdir (name);
}
@@ -1033,30 +1033,37 @@ gnupg_unsetenv (const char *name)
/* Return the current working directory as a malloced string. Return
- NULL and sets ERRNo on error. */
+ NULL and sets ERRNO on error. */
char *
gnupg_getcwd (void)
{
- char *buffer;
- size_t size = 100;
+ return gpgrt_getcwd ();
+}
+
+
+/* A simple wrapper around access. NAME is expected to be utf8
+ * encoded. This function returns an error code and sets ERRNO. */
+gpg_err_code_t
+gnupg_access (const char *name, int mode)
+{
+#if GPGRT_VERSION_NUMBER < 0x012800 /* 1.39 */
+# ifdef HAVE_W32_SYSTEM
+ wchar_t *wfname;
- for (;;)
+ wfname = utf8_to_wchar (fname);
+ if (!wfname)
+ ec = gpg_err_code_from_syserror ();
+ else
{
- buffer = xtrymalloc (size+1);
- if (!buffer)
- return NULL;
-#ifdef HAVE_W32CE_SYSTEM
- strcpy (buffer, "/"); /* Always "/". */
- return buffer;
+ ec = _waccess (wfname, mode)? gpg_err_code_from_syserror () : 0;
+ xfree (wfname);
+ }
+# else
+ return access (name, mode)? gpg_err_code_from_syserror () : 0;
+# endif
#else
- if (getcwd (buffer, size) == buffer)
- return buffer;
- xfree (buffer);
- if (errno != ERANGE)
- return NULL;
- size *= 2;
+ return gpgrt_access (name, mode);
#endif
- }
}
diff --git a/common/sysutils.h b/common/sysutils.h
index daded986f..12b45e47c 100644
--- a/common/sysutils.h
+++ b/common/sysutils.h
@@ -73,6 +73,7 @@ char *gnupg_mkdtemp (char *template);
int gnupg_setenv (const char *name, const char *value, int overwrite);
int gnupg_unsetenv (const char *name);
char *gnupg_getcwd (void);
+gpg_err_code_t gnupg_access (const char *name, int mode);
gpg_error_t gnupg_chuid (const char *user, int silent);
char *gnupg_get_socket_name (int fd);
int gnupg_fd_valid (int fd);
diff --git a/common/t-exectool.c b/common/t-exectool.c
index 9cea2d1be..e1fffdcaa 100644
--- a/common/t-exectool.c
+++ b/common/t-exectool.c
@@ -45,6 +45,7 @@ test_executing_true (void)
char *result;
size_t len;
+ /* Fixme: We should use gpgrt_access here. */
if (access (pgmname, X_OK))
{
if (access (alt_pgmname, X_OK))