summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2023-12-22 12:47:39 +0100
committerWerner Koch <wk@gnupg.org>2023-12-22 12:47:39 +0100
commit239c1fdc28dcd0dc7aa5341be7c966da2231642a (patch)
tree5f05b7ea7ec5b61bf624b8384c3f2825a4d9695a
parentscd:openpgp: Add the length check for new PIN. (diff)
downloadgnupg2-239c1fdc28dcd0dc7aa5341be7c966da2231642a.tar.xz
gnupg2-239c1fdc28dcd0dc7aa5341be7c966da2231642a.zip
common: Add keyword socketdir to gpgconf.ctl
* common/homedir.c (enum wantdir_values): New enums. (unix_rootdir): Change arg to use the enums. Adjust all callers. Add support for the socketdir keyword. (_gnupg_socketdir_internal): Take care of the socketdir keyword in gpgconf.ctl. * doc/tools.texi (Files used by gpgconf): Briefly explain the gpgconf.ctl syntax.
-rw-r--r--common/homedir.c135
-rw-r--r--doc/opt-homedir.texi10
-rw-r--r--doc/tools.texi28
3 files changed, 118 insertions, 55 deletions
diff --git a/common/homedir.c b/common/homedir.c
index 641dba1ae..2b99c9bdc 100644
--- a/common/homedir.c
+++ b/common/homedir.c
@@ -77,6 +77,14 @@
#endif
+/* Mode flags for unix_rootdir. */
+enum wantdir_values {
+ WANTDIR_ROOT = 0,
+ WANTDIR_SYSCONF,
+ WANTDIR_SOCKET
+};
+
+
/* The GnuPG homedir. This is only accessed by the functions
* gnupg_homedir and gnupg_set_homedir. Malloced. */
static char *the_gnupg_homedir;
@@ -491,11 +499,12 @@ w32_rootdir (void)
* file system. If WANT_SYSCONFDIR is true the optional sysconfdir
* entry is returned. */
static const char *
-unix_rootdir (int want_sysconfdir)
+unix_rootdir (enum wantdir_values wantdir)
{
static int checked;
static char *dir; /* for the rootdir */
static char *sdir; /* for the sysconfdir */
+ static char *s2dir; /* for the socketdir */
if (!checked)
{
@@ -510,8 +519,10 @@ unix_rootdir (int want_sysconfdir)
estream_t fp;
char *rootdir;
char *sysconfdir;
+ char *socketdir;
const char *name;
int ignoreall = 0;
+ int okay;
for (;;)
{
@@ -602,12 +613,14 @@ unix_rootdir (int want_sysconfdir)
linelen = 0;
rootdir = NULL;
sysconfdir = NULL;
+ socketdir = NULL;
while ((length = es_read_line (fp, &line, &linelen, NULL)) > 0)
{
static const char *names[] =
{
"rootdir",
"sysconfdir",
+ "socketdir",
".enable"
};
int i;
@@ -662,6 +675,11 @@ unix_rootdir (int want_sysconfdir)
xfree (sysconfdir);
sysconfdir = p;
}
+ else if (!strcmp (name, "socketdir"))
+ {
+ xfree (socketdir);
+ socketdir = p;
+ }
else
{
xfree (rootdir);
@@ -677,6 +695,7 @@ unix_rootdir (int want_sysconfdir)
xfree (line);
xfree (rootdir);
xfree (sysconfdir);
+ xfree (socketdir);
checked = 1;
return NULL;
}
@@ -684,29 +703,26 @@ unix_rootdir (int want_sysconfdir)
xfree (buffer);
xfree (line);
+ okay = 0;
if (ignoreall)
- {
- xfree (rootdir);
- xfree (sysconfdir);
- sdir = dir = NULL;
- }
+ ;
else if (!rootdir || !*rootdir || *rootdir != '/')
{
log_info ("invalid rootdir '%s' specified in gpgconf.ctl\n", rootdir);
- xfree (rootdir);
- xfree (sysconfdir);
- dir = NULL;
}
else if (sysconfdir && (!*sysconfdir || *sysconfdir != '/'))
{
log_info ("invalid sysconfdir '%s' specified in gpgconf.ctl\n",
sysconfdir);
- xfree (rootdir);
- xfree (sysconfdir);
- dir = NULL;
+ }
+ else if (socketdir && (!*socketdir || *socketdir != '/'))
+ {
+ log_info ("invalid socketdir '%s' specified in gpgconf.ctl\n",
+ socketdir);
}
else
{
+ okay = 1;
while (*rootdir && rootdir[strlen (rootdir)-1] == '/')
rootdir[strlen (rootdir)-1] = 0;
dir = rootdir;
@@ -720,11 +736,34 @@ unix_rootdir (int want_sysconfdir)
gpgrt_annotate_leaked_object (sdir);
/* log_info ("want sysconfdir '%s'\n", sdir); */
}
+ if (socketdir)
+ {
+ while (*socketdir && socketdir[strlen (socketdir)-1] == '/')
+ socketdir[strlen (socketdir)-1] = 0;
+ s2dir = socketdir;
+ gpgrt_annotate_leaked_object (s2dir);
+ /* log_info ("want socketdir '%s'\n", s2dir); */
+ }
+ }
+
+ if (!okay)
+ {
+ xfree (rootdir);
+ xfree (sysconfdir);
+ xfree (socketdir);
+ dir = sdir = s2dir = NULL;
}
checked = 1;
}
- return want_sysconfdir? sdir : dir;
+ switch (wantdir)
+ {
+ case WANTDIR_ROOT: return dir;
+ case WANTDIR_SYSCONF: return sdir;
+ case WANTDIR_SOCKET: return s2dir;
+ }
+
+ return NULL; /* Not reached. */
}
#endif /* Unix */
@@ -1035,7 +1074,8 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
};
int i;
struct stat sb;
- char prefix[19 + 1 + 20 + 6 + 1];
+ char prefixbuffer[19 + 1 + 20 + 6 + 1];
+ const char *prefix;
const char *s;
char *name = NULL;
@@ -1050,35 +1090,42 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
* as a background process with no (desktop) user logged in. Thus
* we better don't do that. */
- /* Check whether we have a /run/[gnupg/]user dir. */
- for (i=0; bases[i]; i++)
- {
- snprintf (prefix, sizeof prefix, "%s/user/%u",
- bases[i], (unsigned int)getuid ());
- if (!stat (prefix, &sb) && S_ISDIR(sb.st_mode))
- break;
- }
- if (!bases[i])
+ prefix = unix_rootdir (WANTDIR_SOCKET);
+ if (!prefix)
{
- *r_info |= 2; /* No /run/user directory. */
- goto leave;
- }
+ /* gpgconf.ctl does not specify a directory. Check whether we
+ * have the usual /run/[gnupg/]user dir. */
+ for (i=0; bases[i]; i++)
+ {
+ snprintf (prefixbuffer, sizeof prefixbuffer, "%s/user/%u",
+ bases[i], (unsigned int)getuid ());
+ prefix = prefixbuffer;
+ if (!stat (prefix, &sb) && S_ISDIR(sb.st_mode))
+ break;
+ }
+ if (!bases[i])
+ {
+ *r_info |= 2; /* No /run/user directory. */
+ goto leave;
+ }
- if (sb.st_uid != getuid ())
- {
- *r_info |= 4; /* Not owned by the user. */
- if (!skip_checks)
- goto leave;
- }
+ if (sb.st_uid != getuid ())
+ {
+ *r_info |= 4; /* Not owned by the user. */
+ if (!skip_checks)
+ goto leave;
+ }
- if (strlen (prefix) + 7 >= sizeof prefix)
- {
- *r_info |= 1; /* Ooops: Buffer too short to append "/gnupg". */
- goto leave;
+ if (strlen (prefix) + 7 >= sizeof prefixbuffer)
+ {
+ *r_info |= 1; /* Ooops: Buffer too short to append "/gnupg". */
+ goto leave;
+ }
+ strcat (prefixbuffer, "/gnupg");
}
- strcat (prefix, "/gnupg");
- /* Check whether the gnupg sub directory has proper permissions. */
+ /* Check whether the gnupg sub directory (or the specified diretory)
+ * has proper permissions. */
if (stat (prefix, &sb))
{
if (errno != ENOENT)
@@ -1238,7 +1285,7 @@ gnupg_sysconfdir (void)
}
return name;
#else /*!HAVE_W32_SYSTEM*/
- const char *dir = unix_rootdir (1);
+ const char *dir = unix_rootdir (WANTDIR_SYSCONF);
if (dir)
return dir;
else
@@ -1267,7 +1314,7 @@ gnupg_bindir (void)
else
return rdir;
#else /*!HAVE_W32_SYSTEM*/
- rdir = unix_rootdir (0);
+ rdir = unix_rootdir (WANTDIR_ROOT);
if (rdir)
{
if (!name)
@@ -1294,7 +1341,7 @@ gnupg_libexecdir (void)
static char *name;
const char *rdir;
- rdir = unix_rootdir (0);
+ rdir = unix_rootdir (WANTDIR_ROOT);
if (rdir)
{
if (!name)
@@ -1324,7 +1371,7 @@ gnupg_libdir (void)
#else /*!HAVE_W32_SYSTEM*/
const char *rdir;
- rdir = unix_rootdir (0);
+ rdir = unix_rootdir (WANTDIR_ROOT);
if (rdir)
{
if (!name)
@@ -1355,7 +1402,7 @@ gnupg_datadir (void)
#else /*!HAVE_W32_SYSTEM*/
const char *rdir;
- rdir = unix_rootdir (0);
+ rdir = unix_rootdir (WANTDIR_ROOT);
if (rdir)
{
if (!name)
@@ -1387,7 +1434,7 @@ gnupg_localedir (void)
#else /*!HAVE_W32_SYSTEM*/
const char *rdir;
- rdir = unix_rootdir (0);
+ rdir = unix_rootdir (WANTDIR_ROOT);
if (rdir)
{
if (!name)
diff --git a/doc/opt-homedir.texi b/doc/opt-homedir.texi
index 07993d29d..15ae1970d 100644
--- a/doc/opt-homedir.texi
+++ b/doc/opt-homedir.texi
@@ -13,13 +13,3 @@ directory stated through the environment variable @env{GNUPGHOME} or
On Windows systems it is possible to install GnuPG as a portable
application. In this case only this command line option is
considered, all other ways to set a home directory are ignored.
-
-@efindex gpgconf.ctl
-To install GnuPG as a portable application under Windows, create an
-empty file named @file{gpgconf.ctl} in the same directory as the tool
-@file{gpgconf.exe}. The root of the installation is then that
-directory; or, if @file{gpgconf.exe} has been installed directly below
-a directory named @file{bin}, its parent directory. You also need to
-make sure that the following directories exist and are writable:
-@file{ROOT/home} for the GnuPG home and @file{ROOT@value{LOCALCACHEDIR}}
-for internal cache files.
diff --git a/doc/tools.texi b/doc/tools.texi
index eefa4f9d6..a1c161c3a 100644
--- a/doc/tools.texi
+++ b/doc/tools.texi
@@ -1122,10 +1122,36 @@ More fields may be added in future to the output.
@table @file
+@item gpgconf.ctl
+@cindex gpgconf.ctl
+ Under Unix @file{gpgconf.ctl} may be used to change some of the
+ compiled in directories where the GnuPG components are expected. This
+ file is expected in the same directory as @file{gpgconf}. The
+ physical installation directories are evaluated and no symlinks.
+ Blank lines and lines starting with pound sign are ignored in the
+ file. The keywords must be followed by optional white space, an equal
+ sign, optional white space, and the value. Environment variables are
+ substituted in standard shell manner, the final value must start with
+ a slash, trailing slashes are stripped. Valid keywords are
+ @code{rootdir}, @code{sysconfdir}, @code{socketdir}, and
+ @code{.enable}. No errors are printed for unknown keywords. The
+ @code{.enable} keyword is special: if the keyword is used and its
+ value evaluates to true the entire file is ignored.
+
+ Under Windows this file is used to install GnuPG as a portable
+ application. An empty file named @file{gpgconf.ctl} is expected in
+ the same directory as the tool @file{gpgconf.exe}. The root of the
+ installation is then that directory; or, if @file{gpgconf.exe} has
+ been installed directly below a directory named @file{bin}, its parent
+ directory. You also need to make sure that the following directories
+ exist and are writable: @file{ROOT/home} for the GnuPG home and
+ @file{ROOT@value{LOCALCACHEDIR}} for internal cache files.
+
+
@item /etc/gnupg/gpgconf.conf
@cindex gpgconf.conf
If this file exists, it is processed as a global configuration file.
- This is a legacy mechanism which should not be used tigether with
+ This is a legacy mechanism which should not be used together with
the modern global per component configuration files. A commented
example can be found in the @file{examples} directory of the
distribution.