Allow unicode GnuPG Homedir

This uses gpgconf to look up the homedir of GnuPG and we now
work internally with UTF-8 filenames which are passed through
gpgrt in the end to have Windows UTF-16 conversion. This
fixes a crash / assert when Kleopatra is run from a homedirectory
that contains a non 8 bit character on Windows.
parent 5b994ce3
Pipeline #39713 canceled with stage
......@@ -60,6 +60,6 @@ else()
endif()
endif()
target_link_libraries(kleopatraclientcore Qt5::Widgets KF5::I18n)
target_link_libraries(kleopatraclientcore Qt5::Widgets KF5::I18n Gpgmepp)
install(TARGETS kleopatraclientcore ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
......@@ -32,6 +32,7 @@
#include <assuan.h>
#include <gpg-error.h>
#include <gpgme++/global.h>
#include <algorithm>
#include <string>
......@@ -426,16 +427,8 @@ static QString to_error_string(int err)
static QString gnupg_home_directory()
{
#ifdef Q_OS_WIN
return QFile::decodeName(default_homedir());
#else
const QByteArray gnupgHome = qgetenv("GNUPGHOME");
if (!gnupgHome.isEmpty()) {
return QFile::decodeName(gnupgHome);
} else {
return QDir::homePath() + QLatin1String("/.gnupg");
}
#endif
static const char *hDir = GpgME::dirInfo("homedir");
return QFile::decodeName(hDir);
}
static QString get_default_socket_name()
......@@ -608,11 +601,7 @@ void Command::Private::run()
// give it a bit of time to start up and try a couple of times
for (int i = 0; err && i < 20; ++i) {
msleep(500);
#ifndef HAVE_ASSUAN2
err = assuan_socket_connect(&naked_ctx, QFile::encodeName(socketName).constData(), -1);
#else
err = assuan_socket_connect(ctx.get(), QFile::encodeName(socketName).constData(), -1, 0);
#endif
err = assuan_socket_connect(ctx.get(), socketName.toUtf8().constData(), -1, 0);
}
}
......
......@@ -274,7 +274,7 @@ void UiServer::Private::makeListeningSocket()
}
}
doMakeListeningSocket(QFile::encodeName(fileName));
doMakeListeningSocket(fileName.toUtf8());
actualSocketName = suggestedSocketName;
}
......
......@@ -183,85 +183,3 @@ leave:
RegCloseKey(key_handle);
return result;
}
/* Get the standard home directory. In general this function should
not be used as it does not consider a registry value (under W32) or
the GNUPGHOME encironment variable. It is better to use
default_homedir(). */
static char *
standard_homedir(void)
{
static char *dir;
if (!dir) {
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 *tmp = malloc(strlen(path) + 6 + 1);
if (!tmp) {
dir = strdup ("C:\\gnupg");
return dir;
}
strcpy(tmp, path);
strcat(tmp, "\\gnupg");
dir = tmp;
/* Try to create the directory if it does not yet exists. */
if (access(dir, F_OK)) {
CreateDirectoryA(dir, NULL);
}
} else {
dir = strdup("C:\\gnupg");
}
}
return dir;
}
/* Retrieve the default home directory. */
char *
default_homedir(void)
{
char *dir;
dir = getenv("GNUPGHOME");
if (!dir || !*dir) {
static char *saved_dir;
if (!saved_dir) {
if (!dir || !*dir) {
char *tmp;
tmp = read_w32_registry_string(NULL, "Software\\GNU\\GnuPG",
"HomeDir");
if (tmp && !*tmp) {
free(tmp);
tmp = NULL;
}
if (tmp) {
saved_dir = tmp;
}
}
if (!saved_dir) {
saved_dir = standard_homedir();
}
}
dir = saved_dir;
}
if (!dir || !*dir) {
dir = strdup("C:\\gnupg");
}
return dir;
}
......@@ -30,9 +30,6 @@ HRESULT w32_shgetfolderpath(HWND a, int b, HANDLE c, DWORD d, LPSTR e);
char *read_w32_registry_string(const char *root, const char *dir,
const char *name);
/* Retrieve the default home directory. */
char *default_homedir(void);
#ifdef __cplusplus
#if 0
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment