diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2022-09-16 07:45:20 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2022-09-16 07:45:20 +0900 |
commit | 3c74890c721740d405adcfeb89aeecc03ef49e6c (patch) | |
tree | d4f678c2af3256823abe109bfb70dbc197c3f19d /common | |
parent | b8e317c2a634907810564598cde8cf691ef03d88 (diff) | |
download | gpg2-3c74890c721740d405adcfeb89aeecc03ef49e6c.tar.gz gpg2-3c74890c721740d405adcfeb89aeecc03ef49e6c.tar.bz2 gpg2-3c74890c721740d405adcfeb89aeecc03ef49e6c.zip |
Imported Upstream version 2.3.2upstream/2.3.2
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile.am | 1 | ||||
-rw-r--r-- | common/Makefile.in | 54 | ||||
-rw-r--r-- | common/compliance.c | 3 | ||||
-rw-r--r-- | common/exechelp-w32.c | 6 | ||||
-rw-r--r-- | common/homedir.c | 275 | ||||
-rw-r--r-- | common/keyserver.h | 73 | ||||
-rw-r--r-- | common/name-value.c | 1 | ||||
-rw-r--r-- | common/openpgp-fpr.c | 2 | ||||
-rw-r--r-- | common/recsel.c | 12 | ||||
-rw-r--r-- | common/session-env.c | 5 | ||||
-rw-r--r-- | common/stringhelp.c | 51 | ||||
-rw-r--r-- | common/stringhelp.h | 3 | ||||
-rw-r--r-- | common/sysutils.c | 27 | ||||
-rw-r--r-- | common/sysutils.h | 1 | ||||
-rw-r--r-- | common/t-sexputil.c | 38 | ||||
-rw-r--r-- | common/t-stringhelp.c | 147 | ||||
-rw-r--r-- | common/tlv-builder.c | 1 | ||||
-rw-r--r-- | common/ttyio.c | 22 | ||||
-rw-r--r-- | common/userids.c | 10 | ||||
-rw-r--r-- | common/util.h | 2 |
20 files changed, 498 insertions, 236 deletions
diff --git a/common/Makefile.am b/common/Makefile.am index 62bc9c9..d8368fc 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -59,7 +59,6 @@ common_sources = \ shareddefs.h \ openpgpdefs.h \ gc-opt-flags.h \ - keyserver.h \ sexp-parse.h \ tlv.c tlv.h tlv-builder.c \ init.c init.h \ diff --git a/common/Makefile.in b/common/Makefile.in index 923673d..3e49c78 100644 --- a/common/Makefile.in +++ b/common/Makefile.in @@ -204,18 +204,17 @@ am__libcommon_a_SOURCES_DIST = common-defs.h util.h utilproto.h \ mapstrings.c stringhelp.c stringhelp.h strlist.c strlist.h \ utf8conv.c utf8conv.h logging.h dotlock.c dotlock.h mischelp.c \ mischelp.h status.c status.h shareddefs.h openpgpdefs.h \ - gc-opt-flags.h keyserver.h sexp-parse.h tlv.c tlv.h \ - tlv-builder.c init.c init.h sexputil.c sysutils.c sysutils.h \ - homedir.c gettime.c gettime.h yesno.c b64enc.c b64dec.c zb32.c \ - zb32.h convert.c percent.c mbox-util.c mbox-util.h \ - miscellaneous.c xasprintf.c xreadline.c membuf.c membuf.h \ - ccparray.c ccparray.h iobuf.c iobuf.h ttyio.c ttyio.h \ - asshelp.c asshelp2.c asshelp.h exechelp.h signal.c audit.c \ - audit.h localename.c session-env.c session-env.h userids.c \ - userids.h openpgp-oid.c openpgp-s2k.c ssh-utils.c ssh-utils.h \ - agent-opt.c helpfile.c mkdir_p.c mkdir_p.h exectool.c \ - exectool.h server-help.c server-help.h name-value.c \ - name-value.h recsel.c recsel.h ksba-io-support.c \ + gc-opt-flags.h sexp-parse.h tlv.c tlv.h tlv-builder.c init.c \ + init.h sexputil.c sysutils.c sysutils.h homedir.c gettime.c \ + gettime.h yesno.c b64enc.c b64dec.c zb32.c zb32.h convert.c \ + percent.c mbox-util.c mbox-util.h miscellaneous.c xasprintf.c \ + xreadline.c membuf.c membuf.h ccparray.c ccparray.h iobuf.c \ + iobuf.h ttyio.c ttyio.h asshelp.c asshelp2.c asshelp.h \ + exechelp.h signal.c audit.c audit.h localename.c session-env.c \ + session-env.h userids.c userids.h openpgp-oid.c openpgp-s2k.c \ + ssh-utils.c ssh-utils.h agent-opt.c helpfile.c mkdir_p.c \ + mkdir_p.h exectool.c exectool.h server-help.c server-help.h \ + name-value.c name-value.h recsel.c recsel.h ksba-io-support.c \ ksba-io-support.h openpgp-fpr.c comopt.c comopt.h compliance.c \ compliance.h pkscreening.c pkscreening.h w32-reg.c \ w32-cmdline.c exechelp-w32ce.c exechelp-w32.c exechelp-posix.c \ @@ -270,18 +269,17 @@ am__libcommonpth_a_SOURCES_DIST = common-defs.h util.h utilproto.h \ mapstrings.c stringhelp.c stringhelp.h strlist.c strlist.h \ utf8conv.c utf8conv.h logging.h dotlock.c dotlock.h mischelp.c \ mischelp.h status.c status.h shareddefs.h openpgpdefs.h \ - gc-opt-flags.h keyserver.h sexp-parse.h tlv.c tlv.h \ - tlv-builder.c init.c init.h sexputil.c sysutils.c sysutils.h \ - homedir.c gettime.c gettime.h yesno.c b64enc.c b64dec.c zb32.c \ - zb32.h convert.c percent.c mbox-util.c mbox-util.h \ - miscellaneous.c xasprintf.c xreadline.c membuf.c membuf.h \ - ccparray.c ccparray.h iobuf.c iobuf.h ttyio.c ttyio.h \ - asshelp.c asshelp2.c asshelp.h exechelp.h signal.c audit.c \ - audit.h localename.c session-env.c session-env.h userids.c \ - userids.h openpgp-oid.c openpgp-s2k.c ssh-utils.c ssh-utils.h \ - agent-opt.c helpfile.c mkdir_p.c mkdir_p.h exectool.c \ - exectool.h server-help.c server-help.h name-value.c \ - name-value.h recsel.c recsel.h ksba-io-support.c \ + gc-opt-flags.h sexp-parse.h tlv.c tlv.h tlv-builder.c init.c \ + init.h sexputil.c sysutils.c sysutils.h homedir.c gettime.c \ + gettime.h yesno.c b64enc.c b64dec.c zb32.c zb32.h convert.c \ + percent.c mbox-util.c mbox-util.h miscellaneous.c xasprintf.c \ + xreadline.c membuf.c membuf.h ccparray.c ccparray.h iobuf.c \ + iobuf.h ttyio.c ttyio.h asshelp.c asshelp2.c asshelp.h \ + exechelp.h signal.c audit.c audit.h localename.c session-env.c \ + session-env.h userids.c userids.h openpgp-oid.c openpgp-s2k.c \ + ssh-utils.c ssh-utils.h agent-opt.c helpfile.c mkdir_p.c \ + mkdir_p.h exectool.c exectool.h server-help.c server-help.h \ + name-value.c name-value.h recsel.c recsel.h ksba-io-support.c \ ksba-io-support.h openpgp-fpr.c comopt.c comopt.h compliance.c \ compliance.h pkscreening.c pkscreening.h w32-reg.c \ w32-cmdline.c exechelp-w32ce.c exechelp-w32.c exechelp-posix.c \ @@ -896,10 +894,10 @@ common_sources = common-defs.h util.h utilproto.h fwddecl.h i18n.c \ stringhelp.c stringhelp.h strlist.c strlist.h utf8conv.c \ utf8conv.h logging.h dotlock.c dotlock.h mischelp.c mischelp.h \ status.c status.h shareddefs.h openpgpdefs.h gc-opt-flags.h \ - keyserver.h sexp-parse.h tlv.c tlv.h tlv-builder.c init.c \ - init.h sexputil.c sysutils.c sysutils.h homedir.c gettime.c \ - gettime.h yesno.c b64enc.c b64dec.c zb32.c zb32.h convert.c \ - percent.c mbox-util.c mbox-util.h miscellaneous.c xasprintf.c \ + sexp-parse.h tlv.c tlv.h tlv-builder.c init.c init.h \ + sexputil.c sysutils.c sysutils.h homedir.c gettime.c gettime.h \ + yesno.c b64enc.c b64dec.c zb32.c zb32.h convert.c percent.c \ + mbox-util.c mbox-util.h miscellaneous.c xasprintf.c \ xreadline.c membuf.c membuf.h ccparray.c ccparray.h iobuf.c \ iobuf.h ttyio.c ttyio.h asshelp.c asshelp2.c asshelp.h \ exechelp.h signal.c audit.c audit.h localename.c session-env.c \ diff --git a/common/compliance.c b/common/compliance.c index 217ed09..6c2fcd5 100644 --- a/common/compliance.c +++ b/common/compliance.c @@ -416,7 +416,8 @@ gnupg_cipher_is_allowed (enum gnupg_compliance_mode compliance, int producer, || mode == GCRY_CIPHER_MODE_CFB); case GNUPG_MODULE_NAME_GPGSM: return (mode == GCRY_CIPHER_MODE_NONE - || mode == GCRY_CIPHER_MODE_CBC); + || mode == GCRY_CIPHER_MODE_CBC + || (mode == GCRY_CIPHER_MODE_GCM && !producer)); } log_assert (!"reached"); diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index 0988b90..2a3a550 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -955,14 +955,14 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], else if ((info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK)) { - log_debug ("Using CREATE_BREAKAWAY_FROM_JOB flag\n"); + log_info ("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; " + log_info ("Not using CREATE_BREAKAWAY_FROM_JOB flag; " "JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK is set\n"); } else @@ -970,7 +970,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], /* 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_info ("Not using CREATE_BREAKAWAY_FROM_JOB flag\n"); } } diff --git a/common/homedir.c b/common/homedir.c index 8b54f9d..7969a2c 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -1,6 +1,7 @@ /* homedir.c - Setup the home directory. * Copyright (C) 2004, 2006, 2007, 2010 Free Software Foundation, Inc. * Copyright (C) 2013, 2016 Werner Koch + * Copyright (C) 2021 g10 Code GmbH * * This file is part of GnuPG. * @@ -26,6 +27,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see <https://www.gnu.org/licenses/>. + * SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later) */ #include <config.h> @@ -74,15 +76,15 @@ static byte non_default_homedir; #ifdef HAVE_W32_SYSTEM /* A flag used to indicate that a control file for gpgconf has been - detected. Under Windows the presence of this file indicates a - portable installations and triggers several changes: - - - The GNUGHOME directory is fixed relative to installation - directory. All other means to set the home directory are ignore. - - - All registry variables will be ignored. - - This flag is not used on Unix systems. + * detected. Under Windows the presence of this file indicates a + * portable installations and triggers several changes: + * + * - The GNUGHOME directory is fixed relative to installation + * directory. All other means to set the home directory are ignored. + * + * - All registry variables will be ignored. + * + * This flag is not used on Unix systems. */ static byte w32_portable_app; #endif /*HAVE_W32_SYSTEM*/ @@ -166,7 +168,7 @@ is_gnupg_default_homedir (const char *dir) { int result; char *a = make_absfilename (dir, NULL); - char *b = make_absfilename (GNUPG_DEFAULT_HOMEDIR, NULL); + char *b = make_absfilename (standard_homedir (), NULL); result = !compare_filenames (a, b); xfree (b); xfree (a); @@ -233,7 +235,7 @@ copy_dir_with_fixup (const char *newdir) /* 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 environment variable. It is better to use - default_homedir(). */ + gnupg_homedir(). */ const char * standard_homedir (void) { @@ -248,6 +250,7 @@ standard_homedir (void) if (w32_portable_app) { dir = xstrconcat (rdir, DIRSEP_S "home", NULL); + gpgrt_annotate_leaked_object (dir); } else { @@ -259,6 +262,7 @@ standard_homedir (void) { dir = xstrconcat (path, "\\gnupg", NULL); xfree (path); + gpgrt_annotate_leaked_object (dir); /* Try to create the directory if it does not yet exists. */ if (gnupg_access (dir, F_OK)) @@ -276,7 +280,7 @@ standard_homedir (void) /* Set up the default home directory. The usual --homedir option should be parsed later. */ -const char * +static const char * default_homedir (void) { const char *dir; @@ -336,7 +340,18 @@ default_homedir (void) p = copy_dir_with_fixup (dir); if (p) - dir = p; + { + /* A new buffer has been allocated with proper semantics. + * Assign this to DIR. If DIR is passed again to + * copy_dir_with_fixup there will be no need for a fix up + * and the function returns NULL. Thus we leak only once. + * Setting the homedir is usually a one-off task but might + * be called a second time. We also ignore such extra leaks + * because we don't know who still references the former + * string. */ + gpgrt_annotate_leaked_object (p); + dir = p; + } if (!is_gnupg_default_homedir (dir)) non_default_homedir = 1; @@ -458,6 +473,7 @@ w32_commondir (void) * version. Use the installation directory instead. */ dir = xstrdup (rdir); } + gpgrt_annotate_leaked_object (dir); } return dir; @@ -487,6 +503,10 @@ gnupg_set_homedir (const char *newdir) xfree (the_gnupg_homedir); the_gnupg_homedir = make_absfilename (newdir, NULL);; xfree (tmp); + /* Fixme: Should we use + * gpgrt_annotate_leaked_object(the_gnupg_homedir) + * despite that we may free and allocate a new one in some + * cases? */ } @@ -561,6 +581,7 @@ gnupg_daemon_rootdir (void) name = xstrdup ("/"); /* Error - use the curret top dir instead. */ else name = xstrdup (path); + gpgrt_annotate_leaked_object (name); } return name; @@ -590,8 +611,117 @@ gnupg_daemon_rootdir (void) char * _gnupg_socketdir_internal (int skip_checks, unsigned *r_info) { -#if defined(HAVE_W32_SYSTEM) || !defined(HAVE_STAT) +#if defined(HAVE_W32_SYSTEM) + char *name; + + (void)skip_checks; + + *r_info = 0; + + /* First make sure that non_default_homedir and w32_portable_app can + * be set. */ + gnupg_homedir (); + + if (w32_portable_app) + { + name = xstrconcat (w32_rootdir (), DIRSEP_S, "gnupg", NULL); + } + else + { + char *path; + + path = w32_shgetfolderpath (NULL, + CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE, + NULL, 0); + if (path) + { + name = xstrconcat (path, "\\gnupg", NULL); + xfree (path); + if (gnupg_access (name, F_OK)) + w32_try_mkdir (name); + } + else + { + name = xstrdup (gnupg_homedir ()); + } + } + + /* If a non default homedir is used, we check whether an + * corresponding sub directory below the socket dir is available + * and use that. We hash the non default homedir to keep the new + * subdir short enough. */ + if (non_default_homedir) + { + char sha1buf[20]; + struct stat sb; + char *suffix; + char *p; + + *r_info |= 32; /* Testing subdir. */ + + /* Canonicalize the name to avoid problems with mixed case + * names. Note that we use only 10 bytes of the hash because on + * Windows the account name is also part of the name. */ + suffix = ascii_strlwr (xstrdup (gnupg_homedir ())); + for (p=suffix; *p; p++) + if ( *p == '\\') + *p = '/'; + gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, suffix, strlen (suffix)); + xfree (suffix); + suffix = zb32_encode (sha1buf, 8*10); + if (!suffix) + { + *r_info |= 1; /* Out of core etc. */ + goto leave_w32; + } + p = xstrconcat (name, "\\d.", suffix, NULL); + xfree (suffix); + xfree (name); + name = p; + /* Stat that directory and check constraints. + * The command + * gpgconf --remove-socketdir + * can be used to remove that directory. */ + if (gnupg_stat (name, &sb)) + { + if (errno != ENOENT) + *r_info |= 1; /* stat failed. */ + else if (!skip_checks) + { + /* Try to create the directory and check again. */ + if (gnupg_mkdir (name, "-rwx")) + *r_info |= 16; /* mkdir failed. */ + else if (gnupg_stat (name, &sb)) + { + if (errno != ENOENT) + *r_info |= 1; /* stat failed. */ + else + *r_info |= 64; /* Subdir does not exist. */ + } + else + goto leave_w32; /* Success! */ + } + else + *r_info |= 64; /* Subdir does not exist. */ + if (!skip_checks) + { + xfree (name); + name = NULL; + goto leave_w32; + } + } + } + + leave_w32: + /* If nothing works - fall back to the homedir. */ + if (!name) + { + *r_info |= 128; /* Fallback. */ + name = xstrdup (gnupg_homedir ()); + } + +#elif !defined(HAVE_STAT) char *name; (void)skip_checks; @@ -789,6 +919,7 @@ gnupg_socketdir (void) { unsigned int dummy; name = _gnupg_socketdir_internal (0, &dummy); + gpgrt_annotate_leaked_object (name); } return name; @@ -811,6 +942,7 @@ gnupg_sysconfdir (void) s2 = DIRSEP_S "etc" DIRSEP_S "gnupg"; name = xmalloc (strlen (s1) + strlen (s2) + 1); strcpy (stpcpy (name, s1), s2); + gpgrt_annotate_leaked_object (name); } return name; #else /*!HAVE_W32_SYSTEM*/ @@ -837,7 +969,10 @@ gnupg_bindir (void) static char *name; if (!name) - name = xstrconcat (rdir, DIRSEP_S "bin", NULL); + { + name = xstrconcat (rdir, DIRSEP_S "bin", NULL); + gpgrt_annotate_leaked_object (name); + } return name; } else @@ -867,7 +1002,10 @@ gnupg_libdir (void) static char *name; if (!name) - name = xstrconcat (w32_rootdir (), DIRSEP_S "lib" DIRSEP_S "gnupg", NULL); + { + name = xstrconcat (w32_rootdir (), DIRSEP_S "lib" DIRSEP_S "gnupg", NULL); + gpgrt_annotate_leaked_object (name); + } return name; #else /*!HAVE_W32_SYSTEM*/ return GNUPG_LIBDIR; @@ -881,7 +1019,11 @@ gnupg_datadir (void) static char *name; if (!name) - name = xstrconcat (w32_rootdir (), DIRSEP_S "share" DIRSEP_S "gnupg", NULL); + { + name = xstrconcat (w32_rootdir (), DIRSEP_S "share" DIRSEP_S "gnupg", + NULL); + gpgrt_annotate_leaked_object (name); + } return name; #else /*!HAVE_W32_SYSTEM*/ return GNUPG_DATADIR; @@ -896,82 +1038,14 @@ gnupg_localedir (void) static char *name; if (!name) - name = xstrconcat (w32_rootdir (), DIRSEP_S "share" DIRSEP_S "locale", - NULL); - return name; -#else /*!HAVE_W32_SYSTEM*/ - return LOCALEDIR; -#endif /*!HAVE_W32_SYSTEM*/ -} - - -/* Return the name of the cache directory. The name is allocated in a - static area on the first use. Windows only: If the directory does - not exist it is created. */ -const char * -gnupg_cachedir (void) -{ -#ifdef HAVE_W32_SYSTEM - static const char *dir; - - if (!dir) { - const char *rdir; - - rdir = w32_rootdir (); - if (w32_portable_app) - { - dir = xstrconcat (rdir, - DIRSEP_S, "var", - DIRSEP_S, "cache", - DIRSEP_S, "gnupg", NULL); - } - else - { - char *path; - const char *s1[] = { "GNU", "cache", "gnupg", NULL }; - int s1_len; - const char **comp; - - s1_len = 0; - for (comp = s1; *comp; comp++) - s1_len += 1 + strlen (*comp); - - path = w32_shgetfolderpath (NULL, - CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE, - NULL, 0); - if (path) - { - char *tmp = xmalloc (strlen (path) + s1_len + 1); - char *p; - - p = stpcpy (tmp, path); - for (comp = s1; *comp; comp++) - { - p = stpcpy (p, "\\"); - p = stpcpy (p, *comp); - - if (gnupg_access (tmp, F_OK)) - w32_try_mkdir (tmp); - } - - dir = tmp; - xfree (path); - } - else - { - dir = "c:\\temp\\cache\\gnupg"; -#ifdef HAVE_W32CE_SYSTEM - dir += 2; - w32_try_mkdir ("\\temp\\cache"); - w32_try_mkdir ("\\temp\\cache\\gnupg"); -#endif - } - } + name = xstrconcat (w32_rootdir (), DIRSEP_S "share" DIRSEP_S "locale", + NULL); + gpgrt_annotate_leaked_object (name); } - return dir; + return name; #else /*!HAVE_W32_SYSTEM*/ - return GNUPG_LOCALSTATEDIR "/cache/" PACKAGE_NAME; + return LOCALEDIR; #endif /*!HAVE_W32_SYSTEM*/ } @@ -983,7 +1057,10 @@ gpg_agent_socket_name (void) static char *name; if (!name) - name = make_filename (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL); + { + name = make_filename (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL); + gpgrt_annotate_leaked_object (name); + } return name; } @@ -994,7 +1071,10 @@ dirmngr_socket_name (void) static char *name; if (!name) - name = make_filename (gnupg_socketdir (), DIRMNGR_SOCK_NAME, NULL); + { + name = make_filename (gnupg_socketdir (), DIRMNGR_SOCK_NAME, NULL); + gpgrt_annotate_leaked_object (name); + } return name; } @@ -1006,7 +1086,10 @@ keyboxd_socket_name (void) static char *name; if (!name) - name = make_filename (gnupg_socketdir (), KEYBOXD_SOCK_NAME, NULL); + { + name = make_filename (gnupg_socketdir (), KEYBOXD_SOCK_NAME, NULL); + gpgrt_annotate_leaked_object (name); + } return name; } @@ -1067,6 +1150,8 @@ get_default_pinentry_name (int reset) else xfree (name2); } + if (name) + gpgrt_annotate_leaked_object (name); } return name; @@ -1122,11 +1207,13 @@ gnupg_module_name (int which) #define X(a,b,c) do { \ static char *name; \ - if (!name) \ + if (!name) { \ name = gnupg_build_directory \ ? xstrconcat (gnupg_build_directory, \ DIRSEP_S b DIRSEP_S c EXEEXT_S, NULL) \ : xstrconcat (gnupg_ ## a (), DIRSEP_S c EXEEXT_S, NULL); \ + gpgrt_annotate_leaked_object (name); \ + } \ return name; \ } while (0) diff --git a/common/keyserver.h b/common/keyserver.h deleted file mode 100644 index 850798e..0000000 --- a/common/keyserver.h +++ /dev/null @@ -1,73 +0,0 @@ -/* keyserver.h - Public definitions for gpg keyserver helpers. - * Copyright (C) 2001, 2002, 2011 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of either - * - * - the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 3 of the License, or (at - * your option) any later version. - * - * or - * - * - the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * or both in parallel, as here. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <https://www.gnu.org/licenses/>. - */ - -#ifndef GNUPG_COMMON_KEYSERVER_H -#define GNUPG_COMMON_KEYSERVER_H - -#define KEYSERVER_PROTO_VERSION 1 - -/* These are usable for return codes for the gpgkeys_ process, and - also KEY FAILED codes. */ -#define KEYSERVER_OK 0 /* not an error */ -#define KEYSERVER_INTERNAL_ERROR 1 /* gpgkeys_ internal error */ -#define KEYSERVER_NOT_SUPPORTED 2 /* operation not supported */ -#define KEYSERVER_VERSION_ERROR 3 /* VERSION mismatch */ -#define KEYSERVER_GENERAL_ERROR 4 /* keyserver internal error */ -#define KEYSERVER_NO_MEMORY 5 /* out of memory */ -#define KEYSERVER_KEY_NOT_FOUND 6 /* key not found */ -#define KEYSERVER_KEY_EXISTS 7 /* key already exists */ -#define KEYSERVER_KEY_INCOMPLETE 8 /* key incomplete (EOF) */ -#define KEYSERVER_UNREACHABLE 9 /* unable to contact keyserver */ - -/* Must be 127 due to shell internal magic. */ -#define KEYSERVER_SCHEME_NOT_FOUND 127 - -/* Object to hold information pertaining to a keyserver; it also - allows building a list of keyservers. Note that g10/options.h has - a typedef for this. FIXME: We should make use of the - parse_uri_t. */ -struct keyserver_spec -{ - struct keyserver_spec *next; - char *uri; - char *scheme; - char *auth; - char *host; - char *port; - char *path; - char *opaque; - strlist_t options; - struct - { - unsigned int direct_uri:1; - } flags; -}; - - -#endif /*GNUPG_COMMON_KEYSERVER_H*/ diff --git a/common/name-value.c b/common/name-value.c index 0bd205b..39c3244 100644 --- a/common/name-value.c +++ b/common/name-value.c @@ -724,6 +724,7 @@ do_nvc_parse (nvc_t *result, int *errlinep, estream_t stream, if (raw_value) { err = _nvc_add (*result, name, NULL, raw_value, 1); + name = NULL; if (err) goto leave; } diff --git a/common/openpgp-fpr.c b/common/openpgp-fpr.c index de28c25..7b11008 100644 --- a/common/openpgp-fpr.c +++ b/common/openpgp-fpr.c @@ -265,7 +265,7 @@ compute_openpgp_fpr_ecc (int keyversion, unsigned long timestamp, { if (!kdf || !kdflen || !kdf[0]) { - /* No KDF givem - use the default. */ + /* No KDF given - use the default. */ kdflen = 4; kdf = default_ecdh_params (curvebits); } diff --git a/common/recsel.c b/common/recsel.c index 95c104f..60da4d3 100644 --- a/common/recsel.c +++ b/common/recsel.c @@ -172,6 +172,8 @@ find_next_lc (char *string) * * -- VALUE spans to the end of the expression. * -c The string match in this part is done case-sensitive. + * -t Do not trim leading and trailing spaces from VALUE. + * Note that a space after <op> is here required. * * For example four calls to recsel_parse_expr() with these values for * EXPR @@ -203,6 +205,7 @@ recsel_parse_expr (recsel_expr_t *selector, const char *expression) char *s0, *s; int toend = 0; int xcase = 0; + int notrim = 0; int disjun = 0; char *next_lc = NULL; @@ -232,6 +235,7 @@ recsel_parse_expr (recsel_expr_t *selector, const char *expression) { case '-': toend = 1; break; case 'c': xcase = 1; break; + case 't': notrim = 1; break; default: log_error ("invalid flag '-%c' in expression\n", *expr); recsel_release (se_head); @@ -397,8 +401,11 @@ recsel_parse_expr (recsel_expr_t *selector, const char *expression) return my_error (GPG_ERR_INV_OP); } - while (*s == ' ' || *s == '\t') + if (*s == ' ' || *s == '\t') s++; + if (!notrim) + while (*s == ' ' || *s == '\t') + s++; if (se->op == SELECT_NONEMPTY || se->op == SELECT_ISTRUE) { @@ -431,7 +438,8 @@ recsel_parse_expr (recsel_expr_t *selector, const char *expression) return my_error (GPG_ERR_NO_NAME); } - trim_spaces (se->name + (s - expr)); + if (!notrim) + trim_spaces (se->name + (s - expr)); se->value = se->name + (s - expr); if (!se->value[0] && !(se->op == SELECT_NONEMPTY || se->op == SELECT_ISTRUE)) { diff --git a/common/session-env.c b/common/session-env.c index 5d6b66d..f07d9d1 100644 --- a/common/session-env.c +++ b/common/session-env.c @@ -71,6 +71,11 @@ static struct { "XMODIFIERS" }, /* Used by Xlib to select X input modules (eg "@im=SCIM"). */ { "WAYLAND_DISPLAY" }, /* For the Wayland display engine. */ + { "XDG_SESSION_TYPE" }, /* Used by Qt and other non-GTK toolkits + to check for x11 or wayland. */ + { "QT_QPA_PLATFORM" }, /* Used by Qt to explicitly request + x11 or wayland; in particular, needed + to make Qt use Wayland on Gnome. */ { "GTK_IM_MODULE" }, /* Used by gtk to select gtk input modules (eg "scim-bridge"). */ { "DBUS_SESSION_BUS_ADDRESS" },/* Used by GNOME3 to talk to gcr over diff --git a/common/stringhelp.c b/common/stringhelp.c index 24524e8..4dc1797 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -2,7 +2,7 @@ * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, * 2008, 2009, 2010 Free Software Foundation, Inc. * Copyright (C) 2014 Werner Koch - * Copyright (C) 2015 g10 Code GmbH + * Copyright (C) 2015, 2021 g10 Code GmbH * * This file is part of GnuPG. * @@ -29,6 +29,7 @@ * You should have received a copies of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, see <https://www.gnu.org/licenses/>. + * SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later) */ #include <config.h> @@ -48,7 +49,6 @@ # endif # include <windows.h> #endif -#include <assert.h> #include <limits.h> #include "util.h" @@ -216,7 +216,7 @@ trim_spaces( char *str ) } -/* Same as trim_spaces but only condider, space, tab, cr and lf as space. */ +/* Same as trim_spaces but only consider, space, tab, cr and lf as space. */ char * ascii_trim_spaces (char *str) { @@ -1293,8 +1293,8 @@ strsplit (char *string, char delim, char replacement, int *count) * Returns: A malloced and NULL delimited array with the tokens. On * memory error NULL is returned and ERRNO is set. */ -char ** -strtokenize (const char *string, const char *delim) +static char ** +do_strtokenize (const char *string, const char *delim, int trim) { const char *s; size_t fields; @@ -1333,24 +1333,51 @@ strtokenize (const char *string, const char *delim) for (n = 0, p = buffer; (pend = strpbrk (p, delim)); p = pend + 1) { *pend = 0; + if (trim) + { + while (spacep (p)) + p++; + for (px = pend - 1; px >= p && spacep (px); px--) + *px = 0; + } + result[n++] = p; + } + if (trim) + { while (spacep (p)) p++; - for (px = pend - 1; px >= p && spacep (px); px--) + for (px = p + strlen (p) - 1; px >= p && spacep (px); px--) *px = 0; - result[n++] = p; } - while (spacep (p)) - p++; - for (px = p + strlen (p) - 1; px >= p && spacep (px); px--) - *px = 0; result[n++] = p; result[n] = NULL; - assert ((char*)(result + n + 1) == buffer); + log_assert ((char*)(result + n + 1) == buffer); return result; } +/* Tokenize STRING using the set of delimiters in DELIM. Leading + * spaces and tabs are removed from all tokens. The caller must xfree + * the result. + * + * Returns: A malloced and NULL delimited array with the tokens. On + * memory error NULL is returned and ERRNO is set. + */ +char ** +strtokenize (const char *string, const char *delim) +{ + return do_strtokenize (string, delim, 1); +} + +/* Same as strtokenize but does not trim leading and trailing spaces + * from the fields. */ +char ** +strtokenize_nt (const char *string, const char *delim) +{ + return do_strtokenize (string, delim, 0); +} + /* Split a string into space delimited fields and remove leading and * trailing spaces from each field. A pointer to each field is stored diff --git a/common/stringhelp.h b/common/stringhelp.h index c5f252b..598f698 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -148,6 +148,9 @@ char **strsplit (char *string, char delim, char replacement, int *count); /* Tokenize STRING using the set of delimiters in DELIM. */ char **strtokenize (const char *string, const char *delim); +/* Tokenize STRING using the set of delimiters in DELIM but do not + * trim the tokens. */ +char **strtokenize_nt (const char *string, const char *delim); /* Split STRING into space delimited fields and store them in the * provided ARRAY. */ diff --git a/common/sysutils.c b/common/sysutils.c index 8b2d701..1342d10 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -1004,6 +1004,33 @@ gnupg_chdir (const char *name) } +/* A wrapper around rmdir. NAME is expected to be utf8 encoded. */ +int +gnupg_rmdir (const char *name) +{ +#ifdef HAVE_W32_SYSTEM + int rc; + wchar_t *wfname; + + wfname = utf8_to_wchar (name); + if (!wfname) + rc = 0; + else + { + rc = RemoveDirectoryW (wfname); + if (!rc) + gnupg_w32_set_errno (-1); + xfree (wfname); + } + if (!rc) + return -1; + return 0; +#else + return rmdir (name); +#endif +} + + /* A wrapper around chmod which takes a string for the mode argument. This makes it easier to handle the mode argument which is not defined on all systems. The format of the modestring is the same diff --git a/common/sysutils.h b/common/sysutils.h index 9f2920b..7063da0 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -84,6 +84,7 @@ gpg_error_t gnupg_rename_file (const char *oldname, const char *newname, int *block_signals); int gnupg_mkdir (const char *name, const char *modestr); int gnupg_chdir (const char *name); +int gnupg_rmdir (const char *name); int gnupg_chmod (const char *name, const char *modestr); char *gnupg_mkdtemp (char *template); int gnupg_setenv (const char *name, const char *value, int overwrite); diff --git a/common/t-sexputil.c b/common/t-sexputil.c index d75090c..d6cf335 100644 --- a/common/t-sexputil.c +++ b/common/t-sexputil.c @@ -461,17 +461,33 @@ test_ecc_uncompress (void) if (bbuf) { err = uncompress_ecc_q_in_canon_sexp (bbuf, bbuflen, &rbuf, &rbuflen); - if (err) - fail2 (idx,err); - if (!rbuf) - fail (idx); /* Not converted despite a need for it. */ - - /* log_printcanon (" orig:", abuf, abuflen); */ - /* log_printcanon (" comp:", bbuf, bbuflen); */ - /* log_printcanon ("uncomp:", rbuf, rbuflen); */ - - if (rbuflen != abuflen || memcmp (rbuf, abuf, abuflen)) - fail (idx); + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_CURVE) + { + static int shown; + fprintf (stderr, "%s:%d: test %d failed: %s - ignored\n", + __FILE__,__LINE__, idx, gpg_strerror (err)); + if (!shown) + { + shown = 1; + fprintf (stderr, "This is likely due to a patched" + " version of Libgcrypt with removed support" + " for Brainpool curves\n"); + } + } + else + { + if (err) + fail2 (idx,err); + if (!rbuf) + fail (idx); /* Not converted despite a need for it. */ + + /* log_printcanon (" orig:", abuf, abuflen); */ + /* log_printcanon (" comp:", bbuf, bbuflen); */ + /* log_printcanon ("uncomp:", rbuf, rbuflen); */ + + if (rbuflen != abuflen || memcmp (rbuf, abuf, abuflen)) + fail (idx); + } } xfree (abuf); diff --git a/common/t-stringhelp.c b/common/t-stringhelp.c index 6f7f6f7..5eca5a0 100644 --- a/common/t-stringhelp.c +++ b/common/t-stringhelp.c @@ -1,6 +1,6 @@ /* t-stringhelp.c - Regression tests for stringhelp.c * Copyright (C) 2007 Free Software Foundation, Inc. - * 2015 g10 Code GmbH + * 2015, 2021 g10 Code GmbH * * This file is part of GnuPG. * @@ -27,6 +27,7 @@ * You should have received a copies of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, see <https://www.gnu.org/licenses/>. + * SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later) */ #include <config.h> @@ -34,7 +35,6 @@ #include <stdlib.h> #include <string.h> #include <errno.h> -#include <assert.h> #ifdef HAVE_PWD_H # include <pwd.h> #endif @@ -687,6 +687,144 @@ test_strtokenize (void) static void +test_strtokenize_nt (void) +{ + struct { + const char *s; + const char *delim; + const char *fields_expected[10]; + } tv[] = { + { + "", ":", + { "", NULL } + }, + { + "a", ":", + { "a", NULL } + }, + { + ":", ":", + { "", "", NULL } + }, + { + "::", ":", + { "", "", "", NULL } + }, + { + "a:b:c", ":", + { "a", "b", "c", NULL } + }, + { + "a:b:", ":", + { "a", "b", "", NULL } + }, + { + "a:b", ":", + { "a", "b", NULL } + }, + { + "aa:b:cd", ":", + { "aa", "b", "cd", NULL } + }, + { + "aa::b:cd", ":", + { "aa", "", "b", "cd", NULL } + }, + { + "::b:cd", ":", + { "", "", "b", "cd", NULL } + }, + { + "aa: : b:cd ", ":", + { "aa", " ", " b", "cd ", NULL } + }, + { + " aa: : b: cd ", ":", + { " aa", " ", " b", " cd ", NULL } + }, + { + " ", ":", + { " ", NULL } + }, + { + " :", ":", + { " ", "", NULL } + }, + { + " : ", ":", + { " ", " ", NULL } + }, + { + ": ", ":", + { "", " ", NULL } + }, + { + ": x ", ":", + { "", " x ", NULL } + }, + { + "a:bc:cde:fghi:jklmn::foo:", ":", + { "a", "bc", "cde", "fghi", "jklmn", "", "foo", "", NULL } + }, + { + ",a,bc,,def,", ",", + { "", "a", "bc", "", "def", "", NULL } + }, + { + " a ", " ", + { "", "a", "", NULL } + }, + { + " ", " ", + { "", "", NULL } + }, + { + "", " ", + { "", NULL } + } + }; + + int tidx; + + for (tidx = 0; tidx < DIM(tv); tidx++) + { + char **fields; + int field_count; + int field_count_expected; + int i; + + for (field_count_expected = 0; + tv[tidx].fields_expected[field_count_expected]; + field_count_expected ++) + ; + + fields = strtokenize_nt (tv[tidx].s, tv[tidx].delim); + if (!fields) + fail (tidx * 1000); + else + { + for (field_count = 0; fields[field_count]; field_count++) + ; + if (field_count != field_count_expected) + fail (tidx * 1000); + else + { + for (i = 0; i < field_count_expected; i++) + if (strcmp (tv[tidx].fields_expected[i], fields[i])) + { + printf ("For field %d, expected '%s', but got '%s'\n", + i, tv[tidx].fields_expected[i], fields[i]); + fail (tidx * 1000 + i + 1); + } + } + } + + xfree (fields); + } +} + + +static void test_split_fields (void) { struct { @@ -724,7 +862,7 @@ test_split_fields (void) for (tidx = 0; tidx < DIM(tv); tidx++) { nfields = tv[tidx].nfields; - assert (nfields <= DIM (fields)); + log_assert (nfields <= DIM (fields)); /* Count the fields. */ for (field_count_expected = 0; @@ -799,7 +937,7 @@ test_split_fields_colon (void) for (tidx = 0; tidx < DIM(tv); tidx++) { nfields = tv[tidx].nfields; - assert (nfields <= DIM (fields)); + log_assert (nfields <= DIM (fields)); /* Count the fields. */ for (field_count_expected = 0; @@ -1070,6 +1208,7 @@ main (int argc, char **argv) test_make_absfilename_try (); test_strsplit (); test_strtokenize (); + test_strtokenize_nt (); test_split_fields (); test_split_fields_colon (); test_compare_version_strings (); diff --git a/common/tlv-builder.c b/common/tlv-builder.c index 3b644ca..59e2691 100644 --- a/common/tlv-builder.c +++ b/common/tlv-builder.c @@ -350,6 +350,7 @@ get_tlv_length (int class, int tag, int constructed, size_t length) (void)constructed; /* Not used, but passed for uniformity of such calls. */ + /* coverity[identical_branches] */ if (tag < 0x1f) { buflen++; diff --git a/common/ttyio.c b/common/ttyio.c index 15f7a02..f77c053 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -236,10 +236,24 @@ w32_write_console (const char *string) n = wcslen (wstring); if (!WriteConsoleW (con.out, wstring, n, &nwritten, NULL)) - log_fatal ("WriteConsole failed: %s", w32_strerror (-1)); - if (n != nwritten) - log_fatal ("WriteConsole failed: %lu != %lu\n", - (unsigned long)n, (unsigned long)nwritten); + { + static int shown; + if (!shown) + { + shown = 1; + log_info ("WriteConsole failed: %s", w32_strerror (-1)); + log_info ("Please configure a suitable font for the console\n"); + } + n = strlen (string); + if (!WriteConsoleA (con.out, string, n , &nwritten, NULL)) + log_fatal ("WriteConsole fallback failed: %s", w32_strerror (-1)); + } + else + { + if (n != nwritten) + log_fatal ("WriteConsole failed: %lu != %lu\n", + (unsigned long)n, (unsigned long)nwritten); + } last_prompt_len += n; xfree (wstring); } diff --git a/common/userids.c b/common/userids.c index 0f03896..9d866d5 100644 --- a/common/userids.c +++ b/common/userids.c @@ -115,6 +115,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack) mode = KEYDB_SEARCH_MODE_MAILEND; s++; desc->u.name = s; + desc->name_used = 1; break; case '<': /* An email address. */ @@ -126,24 +127,28 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack) if (!openpgp_hack) s++; desc->u.name = s; + desc->name_used = 1; break; case '@': /* Part of an email address. */ mode = KEYDB_SEARCH_MODE_MAILSUB; s++; desc->u.name = s; + desc->name_used = 1; break; case '=': /* Exact compare. */ mode = KEYDB_SEARCH_MODE_EXACT; s++; desc->u.name = s; + desc->name_used = 1; break; case '*': /* Case insensitive substring search. */ mode = KEYDB_SEARCH_MODE_SUBSTR; s++; desc->u.name = s; + desc->name_used = 1; break; case '+': /* Compare individual words. Note that this has not @@ -151,6 +156,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack) mode = KEYDB_SEARCH_MODE_WORDS; s++; desc->u.name = s; + desc->name_used = 1; break; case '/': /* Subject's DN. */ @@ -161,6 +167,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack) goto out; } desc->u.name = s; + desc->name_used = 1; mode = KEYDB_SEARCH_MODE_SUBJECT; break; @@ -178,6 +185,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack) goto out; } desc->u.name = s; + desc->name_used = 1; mode = KEYDB_SEARCH_MODE_ISSUER; } else @@ -205,6 +213,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack) goto out; } desc->u.name = s; + desc->name_used = 1; mode = KEYDB_SEARCH_MODE_ISSUER_SN; } } @@ -472,6 +481,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack) if (!mode) /* Default to substring search. */ { desc->u.name = s; + desc->name_used = 1; mode = KEYDB_SEARCH_MODE_SUBSTR; } } diff --git a/common/util.h b/common/util.h index 0427bc8..4e12377 100644 --- a/common/util.h +++ b/common/util.h @@ -263,7 +263,6 @@ const char *get_keyalgo_string (enum gcry_pk_algos algo, /*-- homedir.c --*/ const char *standard_homedir (void); -const char *default_homedir (void); void gnupg_set_homedir (const char *newdir); void gnupg_maybe_make_homedir (const char *fname, int quiet); const char *gnupg_homedir (void); @@ -276,7 +275,6 @@ const char *gnupg_libexecdir (void); const char *gnupg_libdir (void); const char *gnupg_datadir (void); const char *gnupg_localedir (void); -const char *gnupg_cachedir (void); const char *gpg_agent_socket_name (void); const char *dirmngr_socket_name (void); const char *keyboxd_socket_name (void); |