Skip to content

Commit 239c1fd

Browse files
committed
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.
1 parent 2376cdf commit 239c1fd

File tree

3 files changed

+118
-55
lines changed

3 files changed

+118
-55
lines changed

common/homedir.c

+91-44
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@
7777
#endif
7878

7979

80+
/* Mode flags for unix_rootdir. */
81+
enum wantdir_values {
82+
WANTDIR_ROOT = 0,
83+
WANTDIR_SYSCONF,
84+
WANTDIR_SOCKET
85+
};
86+
87+
8088
/* The GnuPG homedir. This is only accessed by the functions
8189
* gnupg_homedir and gnupg_set_homedir. Malloced. */
8290
static char *the_gnupg_homedir;
@@ -491,11 +499,12 @@ w32_rootdir (void)
491499
* file system. If WANT_SYSCONFDIR is true the optional sysconfdir
492500
* entry is returned. */
493501
static const char *
494-
unix_rootdir (int want_sysconfdir)
502+
unix_rootdir (enum wantdir_values wantdir)
495503
{
496504
static int checked;
497505
static char *dir; /* for the rootdir */
498506
static char *sdir; /* for the sysconfdir */
507+
static char *s2dir; /* for the socketdir */
499508

500509
if (!checked)
501510
{
@@ -510,8 +519,10 @@ unix_rootdir (int want_sysconfdir)
510519
estream_t fp;
511520
char *rootdir;
512521
char *sysconfdir;
522+
char *socketdir;
513523
const char *name;
514524
int ignoreall = 0;
525+
int okay;
515526

516527
for (;;)
517528
{
@@ -602,12 +613,14 @@ unix_rootdir (int want_sysconfdir)
602613
linelen = 0;
603614
rootdir = NULL;
604615
sysconfdir = NULL;
616+
socketdir = NULL;
605617
while ((length = es_read_line (fp, &line, &linelen, NULL)) > 0)
606618
{
607619
static const char *names[] =
608620
{
609621
"rootdir",
610622
"sysconfdir",
623+
"socketdir",
611624
".enable"
612625
};
613626
int i;
@@ -662,6 +675,11 @@ unix_rootdir (int want_sysconfdir)
662675
xfree (sysconfdir);
663676
sysconfdir = p;
664677
}
678+
else if (!strcmp (name, "socketdir"))
679+
{
680+
xfree (socketdir);
681+
socketdir = p;
682+
}
665683
else
666684
{
667685
xfree (rootdir);
@@ -677,36 +695,34 @@ unix_rootdir (int want_sysconfdir)
677695
xfree (line);
678696
xfree (rootdir);
679697
xfree (sysconfdir);
698+
xfree (socketdir);
680699
checked = 1;
681700
return NULL;
682701
}
683702
es_fclose (fp);
684703
xfree (buffer);
685704
xfree (line);
686705

706+
okay = 0;
687707
if (ignoreall)
688-
{
689-
xfree (rootdir);
690-
xfree (sysconfdir);
691-
sdir = dir = NULL;
692-
}
708+
;
693709
else if (!rootdir || !*rootdir || *rootdir != '/')
694710
{
695711
log_info ("invalid rootdir '%s' specified in gpgconf.ctl\n", rootdir);
696-
xfree (rootdir);
697-
xfree (sysconfdir);
698-
dir = NULL;
699712
}
700713
else if (sysconfdir && (!*sysconfdir || *sysconfdir != '/'))
701714
{
702715
log_info ("invalid sysconfdir '%s' specified in gpgconf.ctl\n",
703716
sysconfdir);
704-
xfree (rootdir);
705-
xfree (sysconfdir);
706-
dir = NULL;
717+
}
718+
else if (socketdir && (!*socketdir || *socketdir != '/'))
719+
{
720+
log_info ("invalid socketdir '%s' specified in gpgconf.ctl\n",
721+
socketdir);
707722
}
708723
else
709724
{
725+
okay = 1;
710726
while (*rootdir && rootdir[strlen (rootdir)-1] == '/')
711727
rootdir[strlen (rootdir)-1] = 0;
712728
dir = rootdir;
@@ -720,11 +736,34 @@ unix_rootdir (int want_sysconfdir)
720736
gpgrt_annotate_leaked_object (sdir);
721737
/* log_info ("want sysconfdir '%s'\n", sdir); */
722738
}
739+
if (socketdir)
740+
{
741+
while (*socketdir && socketdir[strlen (socketdir)-1] == '/')
742+
socketdir[strlen (socketdir)-1] = 0;
743+
s2dir = socketdir;
744+
gpgrt_annotate_leaked_object (s2dir);
745+
/* log_info ("want socketdir '%s'\n", s2dir); */
746+
}
747+
}
748+
749+
if (!okay)
750+
{
751+
xfree (rootdir);
752+
xfree (sysconfdir);
753+
xfree (socketdir);
754+
dir = sdir = s2dir = NULL;
723755
}
724756
checked = 1;
725757
}
726758

727-
return want_sysconfdir? sdir : dir;
759+
switch (wantdir)
760+
{
761+
case WANTDIR_ROOT: return dir;
762+
case WANTDIR_SYSCONF: return sdir;
763+
case WANTDIR_SOCKET: return s2dir;
764+
}
765+
766+
return NULL; /* Not reached. */
728767
}
729768
#endif /* Unix */
730769

@@ -1035,7 +1074,8 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
10351074
};
10361075
int i;
10371076
struct stat sb;
1038-
char prefix[19 + 1 + 20 + 6 + 1];
1077+
char prefixbuffer[19 + 1 + 20 + 6 + 1];
1078+
const char *prefix;
10391079
const char *s;
10401080
char *name = NULL;
10411081

@@ -1050,35 +1090,42 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
10501090
* as a background process with no (desktop) user logged in. Thus
10511091
* we better don't do that. */
10521092

1053-
/* Check whether we have a /run/[gnupg/]user dir. */
1054-
for (i=0; bases[i]; i++)
1055-
{
1056-
snprintf (prefix, sizeof prefix, "%s/user/%u",
1057-
bases[i], (unsigned int)getuid ());
1058-
if (!stat (prefix, &sb) && S_ISDIR(sb.st_mode))
1059-
break;
1060-
}
1061-
if (!bases[i])
1093+
prefix = unix_rootdir (WANTDIR_SOCKET);
1094+
if (!prefix)
10621095
{
1063-
*r_info |= 2; /* No /run/user directory. */
1064-
goto leave;
1065-
}
1096+
/* gpgconf.ctl does not specify a directory. Check whether we
1097+
* have the usual /run/[gnupg/]user dir. */
1098+
for (i=0; bases[i]; i++)
1099+
{
1100+
snprintf (prefixbuffer, sizeof prefixbuffer, "%s/user/%u",
1101+
bases[i], (unsigned int)getuid ());
1102+
prefix = prefixbuffer;
1103+
if (!stat (prefix, &sb) && S_ISDIR(sb.st_mode))
1104+
break;
1105+
}
1106+
if (!bases[i])
1107+
{
1108+
*r_info |= 2; /* No /run/user directory. */
1109+
goto leave;
1110+
}
10661111

1067-
if (sb.st_uid != getuid ())
1068-
{
1069-
*r_info |= 4; /* Not owned by the user. */
1070-
if (!skip_checks)
1071-
goto leave;
1072-
}
1112+
if (sb.st_uid != getuid ())
1113+
{
1114+
*r_info |= 4; /* Not owned by the user. */
1115+
if (!skip_checks)
1116+
goto leave;
1117+
}
10731118

1074-
if (strlen (prefix) + 7 >= sizeof prefix)
1075-
{
1076-
*r_info |= 1; /* Ooops: Buffer too short to append "/gnupg". */
1077-
goto leave;
1119+
if (strlen (prefix) + 7 >= sizeof prefixbuffer)
1120+
{
1121+
*r_info |= 1; /* Ooops: Buffer too short to append "/gnupg". */
1122+
goto leave;
1123+
}
1124+
strcat (prefixbuffer, "/gnupg");
10781125
}
1079-
strcat (prefix, "/gnupg");
10801126

1081-
/* Check whether the gnupg sub directory has proper permissions. */
1127+
/* Check whether the gnupg sub directory (or the specified diretory)
1128+
* has proper permissions. */
10821129
if (stat (prefix, &sb))
10831130
{
10841131
if (errno != ENOENT)
@@ -1238,7 +1285,7 @@ gnupg_sysconfdir (void)
12381285
}
12391286
return name;
12401287
#else /*!HAVE_W32_SYSTEM*/
1241-
const char *dir = unix_rootdir (1);
1288+
const char *dir = unix_rootdir (WANTDIR_SYSCONF);
12421289
if (dir)
12431290
return dir;
12441291
else
@@ -1267,7 +1314,7 @@ gnupg_bindir (void)
12671314
else
12681315
return rdir;
12691316
#else /*!HAVE_W32_SYSTEM*/
1270-
rdir = unix_rootdir (0);
1317+
rdir = unix_rootdir (WANTDIR_ROOT);
12711318
if (rdir)
12721319
{
12731320
if (!name)
@@ -1294,7 +1341,7 @@ gnupg_libexecdir (void)
12941341
static char *name;
12951342
const char *rdir;
12961343

1297-
rdir = unix_rootdir (0);
1344+
rdir = unix_rootdir (WANTDIR_ROOT);
12981345
if (rdir)
12991346
{
13001347
if (!name)
@@ -1324,7 +1371,7 @@ gnupg_libdir (void)
13241371
#else /*!HAVE_W32_SYSTEM*/
13251372
const char *rdir;
13261373

1327-
rdir = unix_rootdir (0);
1374+
rdir = unix_rootdir (WANTDIR_ROOT);
13281375
if (rdir)
13291376
{
13301377
if (!name)
@@ -1355,7 +1402,7 @@ gnupg_datadir (void)
13551402
#else /*!HAVE_W32_SYSTEM*/
13561403
const char *rdir;
13571404

1358-
rdir = unix_rootdir (0);
1405+
rdir = unix_rootdir (WANTDIR_ROOT);
13591406
if (rdir)
13601407
{
13611408
if (!name)
@@ -1387,7 +1434,7 @@ gnupg_localedir (void)
13871434
#else /*!HAVE_W32_SYSTEM*/
13881435
const char *rdir;
13891436

1390-
rdir = unix_rootdir (0);
1437+
rdir = unix_rootdir (WANTDIR_ROOT);
13911438
if (rdir)
13921439
{
13931440
if (!name)

doc/opt-homedir.texi

-10
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,3 @@ directory stated through the environment variable @env{GNUPGHOME} or
1313
On Windows systems it is possible to install GnuPG as a portable
1414
application. In this case only this command line option is
1515
considered, all other ways to set a home directory are ignored.
16-
17-
@efindex gpgconf.ctl
18-
To install GnuPG as a portable application under Windows, create an
19-
empty file named @file{gpgconf.ctl} in the same directory as the tool
20-
@file{gpgconf.exe}. The root of the installation is then that
21-
directory; or, if @file{gpgconf.exe} has been installed directly below
22-
a directory named @file{bin}, its parent directory. You also need to
23-
make sure that the following directories exist and are writable:
24-
@file{ROOT/home} for the GnuPG home and @file{ROOT@value{LOCALCACHEDIR}}
25-
for internal cache files.

doc/tools.texi

+27-1
Original file line numberDiff line numberDiff line change
@@ -1122,10 +1122,36 @@ More fields may be added in future to the output.
11221122

11231123
@table @file
11241124

1125+
@item gpgconf.ctl
1126+
@cindex gpgconf.ctl
1127+
Under Unix @file{gpgconf.ctl} may be used to change some of the
1128+
compiled in directories where the GnuPG components are expected. This
1129+
file is expected in the same directory as @file{gpgconf}. The
1130+
physical installation directories are evaluated and no symlinks.
1131+
Blank lines and lines starting with pound sign are ignored in the
1132+
file. The keywords must be followed by optional white space, an equal
1133+
sign, optional white space, and the value. Environment variables are
1134+
substituted in standard shell manner, the final value must start with
1135+
a slash, trailing slashes are stripped. Valid keywords are
1136+
@code{rootdir}, @code{sysconfdir}, @code{socketdir}, and
1137+
@code{.enable}. No errors are printed for unknown keywords. The
1138+
@code{.enable} keyword is special: if the keyword is used and its
1139+
value evaluates to true the entire file is ignored.
1140+
1141+
Under Windows this file is used to install GnuPG as a portable
1142+
application. An empty file named @file{gpgconf.ctl} is expected in
1143+
the same directory as the tool @file{gpgconf.exe}. The root of the
1144+
installation is then that directory; or, if @file{gpgconf.exe} has
1145+
been installed directly below a directory named @file{bin}, its parent
1146+
directory. You also need to make sure that the following directories
1147+
exist and are writable: @file{ROOT/home} for the GnuPG home and
1148+
@file{ROOT@value{LOCALCACHEDIR}} for internal cache files.
1149+
1150+
11251151
@item /etc/gnupg/gpgconf.conf
11261152
@cindex gpgconf.conf
11271153
If this file exists, it is processed as a global configuration file.
1128-
This is a legacy mechanism which should not be used tigether with
1154+
This is a legacy mechanism which should not be used together with
11291155
the modern global per component configuration files. A commented
11301156
example can be found in the @file{examples} directory of the
11311157
distribution.

0 commit comments

Comments
 (0)