LCOV - code coverage report
Current view: top level - common - homedir.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 91 153 59.5 %
Date: 2016-09-12 12:29:17 Functions: 16 19 84.2 %

          Line data    Source code
       1             : /* homedir.c - Setup the home directory.
       2             :  * Copyright (C) 2004, 2006, 2007, 2010 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2013, 2016 Werner Koch
       4             :  *
       5             :  * This file is part of GnuPG.
       6             :  *
       7             :  * This file is free software; you can redistribute it and/or modify
       8             :  * it under the terms of either
       9             :  *
      10             :  *   - the GNU Lesser General Public License as published by the Free
      11             :  *     Software Foundation; either version 3 of the License, or (at
      12             :  *     your option) any later version.
      13             :  *
      14             :  * or
      15             :  *
      16             :  *   - the GNU General Public License as published by the Free
      17             :  *     Software Foundation; either version 2 of the License, or (at
      18             :  *     your option) any later version.
      19             :  *
      20             :  * or both in parallel, as here.
      21             :  *
      22             :  * This file is distributed in the hope that it will be useful,
      23             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      24             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      25             :  * GNU General Public License for more details.
      26             :  *
      27             :  * You should have received a copy of the GNU General Public License
      28             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      29             :  */
      30             : 
      31             : #include <config.h>
      32             : #include <stdlib.h>
      33             : #include <errno.h>
      34             : #include <fcntl.h>
      35             : #include <unistd.h>
      36             : 
      37             : #ifdef HAVE_W32_SYSTEM
      38             : #include <winsock2.h>   /* Due to the stupid mingw64 requirement to
      39             :                            include this header before windows.h which
      40             :                            is often implicitly included.  */
      41             : #include <shlobj.h>
      42             : #ifndef CSIDL_APPDATA
      43             : #define CSIDL_APPDATA 0x001a
      44             : #endif
      45             : #ifndef CSIDL_LOCAL_APPDATA
      46             : #define CSIDL_LOCAL_APPDATA 0x001c
      47             : #endif
      48             : #ifndef CSIDL_COMMON_APPDATA
      49             : #define CSIDL_COMMON_APPDATA 0x0023
      50             : #endif
      51             : #ifndef CSIDL_FLAG_CREATE
      52             : #define CSIDL_FLAG_CREATE 0x8000
      53             : #endif
      54             : #endif /*HAVE_W32_SYSTEM*/
      55             : 
      56             : #ifdef HAVE_STAT
      57             : #include <sys/stat.h> /* for stat() */
      58             : #endif
      59             : 
      60             : 
      61             : 
      62             : #include "util.h"
      63             : #include "sysutils.h"
      64             : #include "zb32.h"
      65             : 
      66             : /* The GnuPG homedir.  This is only accessed by the functions
      67             :  * gnupg_homedir and gnupg_set_homedir.  Malloced.  */
      68             : static char *the_gnupg_homedir;
      69             : 
      70             : /* Flag indicating that home directory is not the default one.  */
      71             : static byte non_default_homedir;
      72             : 
      73             : 
      74             : #ifdef HAVE_W32_SYSTEM
      75             : /* A flag used to indicate that a control file for gpgconf has been
      76             :    detected.  Under Windows the presence of this file indicates a
      77             :    portable installations and triggers several changes:
      78             : 
      79             :    - The GNUGHOME directory is fixed relative to installation
      80             :      directory.  All other means to set the home directory are ignore.
      81             : 
      82             :    - All registry variables will be ignored.
      83             : 
      84             :    This flag is not used on Unix systems.
      85             :  */
      86             : static byte w32_portable_app;
      87             : #endif /*HAVE_W32_SYSTEM*/
      88             : 
      89             : #ifdef HAVE_W32_SYSTEM
      90             : /* This flag is true if this process' binary has been installed under
      91             :    bin and not in the root directory as often used before GnuPG 2.1. */
      92             : static byte w32_bin_is_bin;
      93             : #endif /*HAVE_W32_SYSTEM*/
      94             : 
      95             : 
      96             : #ifdef HAVE_W32_SYSTEM
      97             : static const char *w32_rootdir (void);
      98             : #endif
      99             : 
     100             : 
     101             : 
     102             : #ifdef HAVE_W32_SYSTEM
     103             : static void
     104             : w32_try_mkdir (const char *dir)
     105             : {
     106             : #ifdef HAVE_W32CE_SYSTEM
     107             :   wchar_t *wdir = utf8_to_wchar (dir);
     108             :   if (wdir)
     109             :     {
     110             :       CreateDirectory (wdir, NULL);
     111             :       xfree (wdir);
     112             :     }
     113             : #else
     114             :   CreateDirectory (dir, NULL);
     115             : #endif
     116             : }
     117             : #endif
     118             : 
     119             : 
     120             : /* This is a helper function to load a Windows function from either of
     121             :    one DLLs. */
     122             : #ifdef HAVE_W32_SYSTEM
     123             : static HRESULT
     124             : w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
     125             : {
     126             :   static int initialized;
     127             :   static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
     128             : 
     129             :   if (!initialized)
     130             :     {
     131             :       static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
     132             :       void *handle;
     133             :       int i;
     134             : 
     135             :       initialized = 1;
     136             : 
     137             :       for (i=0, handle = NULL; !handle && dllnames[i]; i++)
     138             :         {
     139             :           handle = dlopen (dllnames[i], RTLD_LAZY);
     140             :           if (handle)
     141             :             {
     142             :               func = dlsym (handle, "SHGetFolderPathA");
     143             :               if (!func)
     144             :                 {
     145             :                   dlclose (handle);
     146             :                   handle = NULL;
     147             :                 }
     148             :             }
     149             :         }
     150             :     }
     151             : 
     152             :   if (func)
     153             :     return func (a,b,c,d,e);
     154             :   else
     155             :     return -1;
     156             : }
     157             : #endif /*HAVE_W32_SYSTEM*/
     158             : 
     159             : 
     160             : /* Check whether DIR is the default homedir.  */
     161             : static int
     162        1683 : is_gnupg_default_homedir (const char *dir)
     163             : {
     164             :   int result;
     165        1683 :   char *a = make_absfilename (dir, NULL);
     166        1683 :   char *b = make_absfilename (GNUPG_DEFAULT_HOMEDIR, NULL);
     167        1683 :   result = !compare_filenames (a, b);
     168        1683 :   xfree (b);
     169        1683 :   xfree (a);
     170        1683 :   return result;
     171             : }
     172             : 
     173             : 
     174             : /* Get the standard home directory.  In general this function should
     175             :    not be used as it does not consider a registry value (under W32) or
     176             :    the GNUPGHOME environment variable.  It is better to use
     177             :    default_homedir(). */
     178             : const char *
     179          48 : standard_homedir (void)
     180             : {
     181             : #ifdef HAVE_W32_SYSTEM
     182             :   static const char *dir;
     183             : 
     184             :   if (!dir)
     185             :     {
     186             :       const char *rdir;
     187             : 
     188             :       rdir = w32_rootdir ();
     189             :       if (w32_portable_app)
     190             :         {
     191             :           dir = xstrconcat (rdir, DIRSEP_S "home", NULL);
     192             :         }
     193             :       else
     194             :         {
     195             :           char path[MAX_PATH];
     196             : 
     197             :           /* It might be better to use LOCAL_APPDATA because this is
     198             :              defined as "non roaming" and thus more likely to be kept
     199             :              locally.  For private keys this is desired.  However,
     200             :              given that many users copy private keys anyway forth and
     201             :              back, using a system roaming services might be better
     202             :              than to let them do it manually.  A security conscious
     203             :              user will anyway use the registry entry to have better
     204             :              control.  */
     205             :           if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
     206             :                                    NULL, 0, path) >= 0)
     207             :             {
     208             :               char *tmp = xmalloc (strlen (path) + 6 +1);
     209             :               strcpy (stpcpy (tmp, path), "\\gnupg");
     210             :               dir = tmp;
     211             : 
     212             :               /* Try to create the directory if it does not yet exists.  */
     213             :               if (access (dir, F_OK))
     214             :                 w32_try_mkdir (dir);
     215             :             }
     216             :           else
     217             :             dir = GNUPG_DEFAULT_HOMEDIR;
     218             :         }
     219             :     }
     220             :   return dir;
     221             : #else/*!HAVE_W32_SYSTEM*/
     222          48 :   return GNUPG_DEFAULT_HOMEDIR;
     223             : #endif /*!HAVE_W32_SYSTEM*/
     224             : }
     225             : 
     226             : /* Set up the default home directory.  The usual --homedir option
     227             :    should be parsed later. */
     228             : const char *
     229        2086 : default_homedir (void)
     230             : {
     231             :   const char *dir;
     232             : 
     233             : #ifdef HAVE_W32_SYSTEM
     234             :   /* For a portable application we only use the standard homedir.  */
     235             :   w32_rootdir ();
     236             :   if (w32_portable_app)
     237             :     return standard_homedir ();
     238             : #endif /*HAVE_W32_SYSTEM*/
     239             : 
     240        2086 :   dir = getenv ("GNUPGHOME");
     241             : #ifdef HAVE_W32_SYSTEM
     242             :   if (!dir || !*dir)
     243             :     {
     244             :       static const char *saved_dir;
     245             : 
     246             :       if (!saved_dir)
     247             :         {
     248             :           if (!dir || !*dir)
     249             :             {
     250             :               char *tmp;
     251             : 
     252             :               tmp = read_w32_registry_string (NULL,
     253             :                                               GNUPG_REGISTRY_DIR,
     254             :                                               "HomeDir");
     255             :               if (tmp && !*tmp)
     256             :                 {
     257             :                   xfree (tmp);
     258             :                   tmp = NULL;
     259             :                 }
     260             :               if (tmp)
     261             :                 saved_dir = tmp;
     262             :             }
     263             : 
     264             :           if (!saved_dir)
     265             :             saved_dir = standard_homedir ();
     266             :         }
     267             :       dir = saved_dir;
     268             :     }
     269             : #endif /*HAVE_W32_SYSTEM*/
     270        2086 :   if (!dir || !*dir)
     271         499 :     dir = GNUPG_DEFAULT_HOMEDIR;
     272        1587 :   else if (!is_gnupg_default_homedir (dir))
     273        1587 :     non_default_homedir = 1;
     274             : 
     275        2086 :   return dir;
     276             : }
     277             : 
     278             : 
     279             : #ifdef HAVE_W32_SYSTEM
     280             : /* Check whether gpgconf is installed and if so read the gpgconf.ctl
     281             :    file. */
     282             : static void
     283             : check_portable_app (const char *dir)
     284             : {
     285             :   char *fname;
     286             : 
     287             :   fname = xstrconcat (dir, DIRSEP_S "gpgconf.exe", NULL);
     288             :   if (!access (fname, F_OK))
     289             :     {
     290             :       strcpy (fname + strlen (fname) - 3, "ctl");
     291             :       if (!access (fname, F_OK))
     292             :         {
     293             :           /* gpgconf.ctl file found.  Record this fact.  */
     294             :           w32_portable_app = 1;
     295             :           {
     296             :             unsigned int flags;
     297             :             log_get_prefix (&flags);
     298             :             log_set_prefix (NULL, (flags | GPGRT_LOG_NO_REGISTRY));
     299             :           }
     300             :           /* FIXME: We should read the file to detect special flags
     301             :              and print a warning if we don't understand them  */
     302             :         }
     303             :     }
     304             :   xfree (fname);
     305             : }
     306             : 
     307             : 
     308             : /* Determine the root directory of the gnupg installation on Windows.  */
     309             : static const char *
     310             : w32_rootdir (void)
     311             : {
     312             :   static int got_dir;
     313             :   static char dir[MAX_PATH+5];
     314             : 
     315             :   if (!got_dir)
     316             :     {
     317             :       char *p;
     318             :       int rc;
     319             :       wchar_t wdir [MAX_PATH+5];
     320             : 
     321             :       rc = GetModuleFileNameW (NULL, wdir, MAX_PATH);
     322             :       if (rc && WideCharToMultiByte (CP_UTF8, 0, wdir, -1, dir, MAX_PATH-4,
     323             :                                      NULL, NULL) < 0)
     324             :         rc = 0;
     325             :       if (!rc)
     326             :         {
     327             :           log_debug ("GetModuleFileName failed: %s\n", w32_strerror (-1));
     328             :           *dir = 0;
     329             :         }
     330             :       got_dir = 1;
     331             :       p = strrchr (dir, DIRSEP_C);
     332             :       if (p)
     333             :         {
     334             :           *p = 0;
     335             : 
     336             :           check_portable_app (dir);
     337             : 
     338             :           /* If we are installed below "bin" we strip that and use
     339             :              the top directory instead.  */
     340             :           p = strrchr (dir, DIRSEP_C);
     341             :           if (p && !strcmp (p+1, "bin"))
     342             :             {
     343             :               *p = 0;
     344             :               w32_bin_is_bin = 1;
     345             :             }
     346             :         }
     347             :       if (!p)
     348             :         {
     349             :           log_debug ("bad filename '%s' returned for this process\n", dir);
     350             :           *dir = 0;
     351             :         }
     352             :     }
     353             : 
     354             :   if (*dir)
     355             :     return dir;
     356             :   /* Fallback to the hardwired value. */
     357             :   return GNUPG_LIBEXECDIR;
     358             : }
     359             : 
     360             : static const char *
     361             : w32_commondir (void)
     362             : {
     363             :   static char *dir;
     364             : 
     365             :   if (!dir)
     366             :     {
     367             :       const char *rdir;
     368             :       char path[MAX_PATH];
     369             : 
     370             :       /* Make sure that w32_rootdir has been called so that we are
     371             :          able to check the portable application flag.  The common dir
     372             :          is the identical to the rootdir.  In that case there is also
     373             :          no need to strdup its value.  */
     374             :       rdir = w32_rootdir ();
     375             :       if (w32_portable_app)
     376             :         return rdir;
     377             : 
     378             :       if (w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA,
     379             :                                NULL, 0, path) >= 0)
     380             :         {
     381             :           char *tmp = xmalloc (strlen (path) + 4 +1);
     382             :           strcpy (stpcpy (tmp, path), "\\GNU");
     383             :           dir = tmp;
     384             :           /* No auto create of the directory.  Either the installer or
     385             :              the admin has to create these directories.  */
     386             :         }
     387             :       else
     388             :         {
     389             :           /* Ooops: Not defined - probably an old Windows version.
     390             :              Use the installation directory instead.  */
     391             :           dir = xstrdup (rdir);
     392             :         }
     393             :     }
     394             : 
     395             :   return dir;
     396             : }
     397             : #endif /*HAVE_W32_SYSTEM*/
     398             : 
     399             : 
     400             : /* Change the homedir.  Some care must be taken to set this early
     401             :  * enough because previous calls to gnupg_homedir may else return a
     402             :  * different string.  */
     403             : void
     404        1923 : gnupg_set_homedir (const char *newdir)
     405             : {
     406        1923 :   if (!newdir || !*newdir)
     407        1827 :     newdir = default_homedir ();
     408          96 :   else if (!is_gnupg_default_homedir (newdir))
     409          96 :     non_default_homedir = 1;
     410        1923 :   xfree (the_gnupg_homedir);
     411        1923 :   the_gnupg_homedir = make_absfilename (newdir, NULL);;
     412        1923 : }
     413             : 
     414             : 
     415             : /* Return the homedir.  The returned string is valid until another
     416             :  * gnupg-set-homedir call.  This is always an absolute directory name.
     417             :  * The function replaces the former global var opt.homedir.  */
     418             : const char *
     419       17668 : gnupg_homedir (void)
     420             : {
     421             :   /* If a homedir has not been set, set it to the default.  */
     422       17668 :   if (!the_gnupg_homedir)
     423         259 :     the_gnupg_homedir = make_absfilename (default_homedir (), NULL);
     424       17668 :   return the_gnupg_homedir;
     425             : }
     426             : 
     427             : 
     428             : /* Return whether the home dir is the default one.  */
     429             : int
     430           5 : gnupg_default_homedir_p (void)
     431             : {
     432           5 :   return !non_default_homedir;
     433             : }
     434             : 
     435             : 
     436             : /* Helper for gnupg-socketdir.  This is a global function, so that
     437             :  * gpgconf can use it for its --create-socketdir command.  If
     438             :  * SKIP_CHECKS is set permission checks etc. are not done.  The
     439             :  * function always returns a malloced directory name and stores these
     440             :  * bit flags at R_INFO:
     441             :  *
     442             :  *   1 := Internal error, stat failed, out of core, etc.
     443             :  *   2 := No /run/user directory.
     444             :  *   4 := Directory not owned by the user, not a directory
     445             :  *        or wrong permissions.
     446             :  *   8 := Same as 4 but for the subdir.
     447             :  *  16 := mkdir failed
     448             :  *  32 := Non default homedir; checking subdir.
     449             :  *  64 := Subdir does not exist.
     450             :  * 128 := Using homedir as fallback.
     451             :  */
     452             : char *
     453         747 : _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
     454             : {
     455             : #if defined(HAVE_W32_SYSTEM) || !defined(HAVE_STAT)
     456             : 
     457             :   char *name;
     458             : 
     459             :   (void)skip_checks;
     460             :   *r_info = 0;
     461             :   name = xstrdup (gnupg_homedir ());
     462             : 
     463             : #else /* Unix and stat(2) available. */
     464             : 
     465             :   static const char * const bases[] = { "/run", "/var/run", NULL};
     466             :   int i;
     467             :   struct stat sb;
     468             :   char prefix[13 + 1 + 20 + 6 + 1];
     469             :   const char *s;
     470         747 :   char *name = NULL;
     471             : 
     472         747 :   *r_info = 0;
     473             : 
     474             :   /* First make sure that non_default_homedir can be set.  */
     475         747 :   gnupg_homedir ();
     476             : 
     477             :   /* It has been suggested to first check XDG_RUNTIME_DIR envvar.
     478             :    * However, the specs state that the lifetime of the directory MUST
     479             :    * be bound to the user being logged in.  Now GnuPG may also be run
     480             :    * as a background process with no (desktop) user logged in.  Thus
     481             :    * we better don't do that.  */
     482             : 
     483             :   /* Check whether we have a /run/user dir.  */
     484         747 :   for (i=0; bases[i]; i++)
     485             :     {
     486         747 :       snprintf (prefix, sizeof prefix, "%s/user/%u",
     487             :                 bases[i], (unsigned int)getuid ());
     488         747 :       if (!stat (prefix, &sb) && S_ISDIR(sb.st_mode))
     489         747 :         break;
     490             :     }
     491         747 :   if (!bases[i])
     492             :     {
     493           0 :       *r_info |= 2; /* No /run/user directory.  */
     494           0 :       goto leave;
     495             :     }
     496             : 
     497         747 :   if (sb.st_uid != getuid ())
     498             :     {
     499           0 :       *r_info |= 4; /* Not owned by the user.  */
     500           0 :       if (!skip_checks)
     501           0 :         goto leave;
     502             :     }
     503             : 
     504         747 :   if (strlen (prefix) + 7 >= sizeof prefix)
     505             :     {
     506           0 :       *r_info |= 1; /* Ooops: Buffer too short to append "/gnupg".  */
     507           0 :       goto leave;
     508             :     }
     509         747 :   strcat (prefix, "/gnupg");
     510             : 
     511             :   /* Check whether the gnupg sub directory has proper permissions.  */
     512         747 :   if (stat (prefix, &sb))
     513             :     {
     514           0 :       if (errno != ENOENT)
     515             :         {
     516           0 :           *r_info |= 1; /* stat failed.  */
     517           0 :           goto leave;
     518             :         }
     519             : 
     520             :       /* Try to create the directory and check again.  */
     521           0 :       if (gnupg_mkdir (prefix, "-rwx"))
     522             :         {
     523           0 :           *r_info |= 16; /* mkdir failed.  */
     524           0 :           goto leave;
     525             :         }
     526           0 :       if (stat (prefix, &sb))
     527             :         {
     528           0 :           *r_info |= 1; /* stat failed.  */
     529           0 :           goto leave;
     530             :         }
     531             :     }
     532             :   /* Check that it is a directory, owned by the user, and only the
     533             :    * user has permissions to use it.  */
     534         747 :   if (!S_ISDIR(sb.st_mode)
     535         747 :       || sb.st_uid != getuid ()
     536         747 :       || (sb.st_mode & (S_IRWXG|S_IRWXO)))
     537             :     {
     538           0 :       *r_info |= 4; /* Bad permissions or not a directory. */
     539           0 :       if (!skip_checks)
     540           0 :         goto leave;
     541             :     }
     542             : 
     543             :   /* If a non default homedir is used, we check whether an
     544             :    * corresponding sub directory below the socket dir is available
     545             :    * and use that.  We has the non default homedir to keep the new
     546             :    * subdir short enough.  */
     547         747 :   if (non_default_homedir)
     548             :     {
     549             :       char sha1buf[20];
     550             :       char *suffix;
     551             : 
     552         747 :       *r_info |= 32; /* Testing subdir.  */
     553         747 :       s = gnupg_homedir ();
     554         747 :       gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, s, strlen (s));
     555         747 :       suffix = zb32_encode (sha1buf, 8*15);
     556         747 :       if (!suffix)
     557             :         {
     558           0 :           *r_info |= 1; /* Out of core etc. */
     559         747 :           goto leave;
     560             :         }
     561         747 :       name = strconcat (prefix, "/d.", suffix, NULL);
     562         747 :       xfree (suffix);
     563         747 :       if (!name)
     564             :         {
     565           0 :           *r_info |= 1; /* Out of core etc. */
     566           0 :           goto leave;
     567             :         }
     568             : 
     569             :       /* Stat that directory and check constraints.  Note that we
     570             :        * do not auto create such a directory because we would not
     571             :        * have a way to remove it.  Thus the directory needs to be
     572             :        * pre-created.  The command
     573             :        *    gpgconf --create-socketdir
     574             :        * can be used tocreate that directory.  */
     575         747 :       if (stat (name, &sb))
     576             :         {
     577         747 :           if (errno != ENOENT)
     578           0 :             *r_info |= 1; /* stat failed. */
     579             :           else
     580         747 :             *r_info |= 64; /* Subdir does not exist.  */
     581         747 :           if (!skip_checks)
     582             :             {
     583         747 :               xfree (name);
     584         747 :               name = NULL;
     585         747 :               goto leave;
     586             :             }
     587             :         }
     588           0 :       else if (!S_ISDIR(sb.st_mode)
     589           0 :                || sb.st_uid != getuid ()
     590           0 :                || (sb.st_mode & (S_IRWXG|S_IRWXO)))
     591             :         {
     592           0 :           *r_info |= 8; /* Bad permissions or subdir is not a directory.  */
     593           0 :           if (!skip_checks)
     594             :             {
     595           0 :               xfree (name);
     596           0 :               name = NULL;
     597           0 :               goto leave;
     598             :             }
     599             :         }
     600             :     }
     601             :   else
     602           0 :     name = xstrdup (prefix);
     603             : 
     604             :  leave:
     605             :   /* If nothing works fall back to the homedir.  */
     606         747 :   if (!name)
     607             :     {
     608         747 :       *r_info |= 128; /* Fallback.  */
     609         747 :       name = xstrdup (gnupg_homedir ());
     610             :     }
     611             : 
     612             : #endif /* Unix */
     613             : 
     614         747 :   return name;
     615             : }
     616             : 
     617             : 
     618             : /*
     619             :  * Return the name of the socket dir.  That is the directory used for
     620             :  * the IPC local sockets.  This is an absolute directory name.
     621             :  */
     622             : const char *
     623         825 : gnupg_socketdir (void)
     624             : {
     625             :   static char *name;
     626             : 
     627         825 :   if (!name)
     628             :     {
     629             :       unsigned int dummy;
     630         747 :       name = _gnupg_socketdir_internal (0, &dummy);
     631             :     }
     632             : 
     633         825 :   return name;
     634             : }
     635             : 
     636             : 
     637             : /* Return the name of the sysconfdir.  This is a static string.  This
     638             :    function is required because under Windows we can't simply compile
     639             :    it in.  */
     640             : const char *
     641           1 : gnupg_sysconfdir (void)
     642             : {
     643             : #ifdef HAVE_W32_SYSTEM
     644             :   static char *name;
     645             : 
     646             :   if (!name)
     647             :     {
     648             :       const char *s1, *s2;
     649             :       s1 = w32_commondir ();
     650             :       s2 = DIRSEP_S "etc" DIRSEP_S "gnupg";
     651             :       name = xmalloc (strlen (s1) + strlen (s2) + 1);
     652             :       strcpy (stpcpy (name, s1), s2);
     653             :     }
     654             :   return name;
     655             : #else /*!HAVE_W32_SYSTEM*/
     656           1 :   return GNUPG_SYSCONFDIR;
     657             : #endif /*!HAVE_W32_SYSTEM*/
     658             : }
     659             : 
     660             : 
     661             : const char *
     662          48 : gnupg_bindir (void)
     663             : {
     664             : #if defined (HAVE_W32CE_SYSTEM)
     665             :   static char *name;
     666             : 
     667             :   if (!name)
     668             :     name = xstrconcat (w32_rootdir (), DIRSEP_S "bin", NULL);
     669             :   return name;
     670             : #elif defined(HAVE_W32_SYSTEM)
     671             :   const char *rdir;
     672             : 
     673             :   rdir = w32_rootdir ();
     674             :   if (w32_bin_is_bin)
     675             :     {
     676             :       static char *name;
     677             : 
     678             :       if (!name)
     679             :         name = xstrconcat (rdir, DIRSEP_S "bin", NULL);
     680             :       return name;
     681             :     }
     682             :   else
     683             :     return rdir;
     684             : #else /*!HAVE_W32_SYSTEM*/
     685          48 :   return GNUPG_BINDIR;
     686             : #endif /*!HAVE_W32_SYSTEM*/
     687             : }
     688             : 
     689             : 
     690             : /* Return the name of the libexec directory.  The name is allocated in
     691             :    a static area on the first use.  This function won't fail. */
     692             : const char *
     693           2 : gnupg_libexecdir (void)
     694             : {
     695             : #ifdef HAVE_W32_SYSTEM
     696             :   return gnupg_bindir ();
     697             : #else /*!HAVE_W32_SYSTEM*/
     698           2 :   return GNUPG_LIBEXECDIR;
     699             : #endif /*!HAVE_W32_SYSTEM*/
     700             : }
     701             : 
     702             : const char *
     703           1 : gnupg_libdir (void)
     704             : {
     705             : #ifdef HAVE_W32_SYSTEM
     706             :   static char *name;
     707             : 
     708             :   if (!name)
     709             :     name = xstrconcat (w32_rootdir (), DIRSEP_S "lib" DIRSEP_S "gnupg", NULL);
     710             :   return name;
     711             : #else /*!HAVE_W32_SYSTEM*/
     712           1 :   return GNUPG_LIBDIR;
     713             : #endif /*!HAVE_W32_SYSTEM*/
     714             : }
     715             : 
     716             : const char *
     717           2 : gnupg_datadir (void)
     718             : {
     719             : #ifdef HAVE_W32_SYSTEM
     720             :   static char *name;
     721             : 
     722             :   if (!name)
     723             :     name = xstrconcat (w32_rootdir (), DIRSEP_S "share" DIRSEP_S "gnupg", NULL);
     724             :   return name;
     725             : #else /*!HAVE_W32_SYSTEM*/
     726           2 :   return GNUPG_DATADIR;
     727             : #endif /*!HAVE_W32_SYSTEM*/
     728             : }
     729             : 
     730             : 
     731             : const char *
     732           1 : gnupg_localedir (void)
     733             : {
     734             : #ifdef HAVE_W32_SYSTEM
     735             :   static char *name;
     736             : 
     737             :   if (!name)
     738             :     name = xstrconcat (w32_rootdir (), DIRSEP_S "share" DIRSEP_S "locale",
     739             :                        NULL);
     740             :   return name;
     741             : #else /*!HAVE_W32_SYSTEM*/
     742           1 :   return LOCALEDIR;
     743             : #endif /*!HAVE_W32_SYSTEM*/
     744             : }
     745             : 
     746             : 
     747             : /* Return the name of the cache directory.  The name is allocated in a
     748             :    static area on the first use.  Windows only: If the directory does
     749             :    not exist it is created.  */
     750             : const char *
     751           0 : gnupg_cachedir (void)
     752             : {
     753             : #ifdef HAVE_W32_SYSTEM
     754             :   static const char *dir;
     755             : 
     756             :   if (!dir)
     757             :     {
     758             :       const char *rdir;
     759             : 
     760             :       rdir = w32_rootdir ();
     761             :       if (w32_portable_app)
     762             :         {
     763             :           dir = xstrconcat (rdir,
     764             :                             DIRSEP_S, "var",
     765             :                             DIRSEP_S, "cache",
     766             :                             DIRSEP_S, "gnupg", NULL);
     767             :         }
     768             :       else
     769             :         {
     770             :           char path[MAX_PATH];
     771             :           const char *s1[] = { "GNU", "cache", "gnupg", NULL };
     772             :           int s1_len;
     773             :           const char **comp;
     774             : 
     775             :           s1_len = 0;
     776             :           for (comp = s1; *comp; comp++)
     777             :             s1_len += 1 + strlen (*comp);
     778             : 
     779             :           if (w32_shgetfolderpath (NULL, CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE,
     780             :                                    NULL, 0, path) >= 0)
     781             :             {
     782             :               char *tmp = xmalloc (strlen (path) + s1_len + 1);
     783             :               char *p;
     784             : 
     785             :               p = stpcpy (tmp, path);
     786             :               for (comp = s1; *comp; comp++)
     787             :                 {
     788             :                   p = stpcpy (p, "\\");
     789             :                   p = stpcpy (p, *comp);
     790             : 
     791             :                   if (access (tmp, F_OK))
     792             :                     w32_try_mkdir (tmp);
     793             :                 }
     794             : 
     795             :               dir = tmp;
     796             :             }
     797             :           else
     798             :             {
     799             :               dir = "c:\\temp\\cache\\gnupg";
     800             : #ifdef HAVE_W32CE_SYSTEM
     801             :               dir += 2;
     802             :               w32_try_mkdir ("\\temp\\cache");
     803             :               w32_try_mkdir ("\\temp\\cache\\gnupg");
     804             : #endif
     805             :             }
     806             :         }
     807             :     }
     808             :   return dir;
     809             : #else /*!HAVE_W32_SYSTEM*/
     810           0 :   return GNUPG_LOCALSTATEDIR "/cache/" PACKAGE_NAME;
     811             : #endif /*!HAVE_W32_SYSTEM*/
     812             : }
     813             : 
     814             : 
     815             : /* Return the user socket name used by DirMngr.  */
     816             : const char *
     817           1 : dirmngr_socket_name (void)
     818             : {
     819             :   static char *name;
     820             : 
     821           1 :   if (!name)
     822           1 :     name = make_filename (gnupg_socketdir (), DIRMNGR_SOCK_NAME, NULL);
     823           1 :   return name;
     824             : }
     825             : 
     826             : 
     827             : /* Return the default pinentry name.  If RESET is true the internal
     828             :    cache is first flushed.  */
     829             : static const char *
     830           0 : get_default_pinentry_name (int reset)
     831             : {
     832             :   static struct {
     833             :     const char *(*rfnc)(void);
     834             :     const char *name;
     835             :   } names[] = {
     836             :     /* The first entry is what we return in case we found no
     837             :        other pinentry.  */
     838             :     { gnupg_bindir, DIRSEP_S "pinentry" EXEEXT_S },
     839             : #ifdef HAVE_W32_SYSTEM
     840             :     /* Try Gpg4win directory (with bin and without.) */
     841             :     { w32_rootdir, "\\..\\Gpg4win\\bin\\pinentry.exe" },
     842             :     { w32_rootdir, "\\..\\Gpg4win\\pinentry.exe" },
     843             :     /* Try old Gpgwin directory.  */
     844             :     { w32_rootdir, "\\..\\GNU\\GnuPG\\pinentry.exe" },
     845             :     /* Try a Pinentry from the common GNU dir.  */
     846             :     { w32_rootdir, "\\..\\GNU\\bin\\pinentry.exe" },
     847             : #endif
     848             :     /* Last chance is a pinentry-basic (which comes with the
     849             :        GnuPG 2.1 Windows installer).  */
     850             :     { gnupg_bindir, DIRSEP_S "pinentry-basic" EXEEXT_S }
     851             :   };
     852             :   static char *name;
     853             : 
     854           0 :   if (reset)
     855             :     {
     856           0 :       xfree (name);
     857           0 :       name = NULL;
     858             :     }
     859             : 
     860           0 :   if (!name)
     861             :     {
     862             :       int i;
     863             : 
     864           0 :       for (i=0; i < DIM(names); i++)
     865             :         {
     866             :           char *name2;
     867             : 
     868           0 :           name2 = xstrconcat (names[i].rfnc (), names[i].name, NULL);
     869           0 :           if (!access (name2, F_OK))
     870             :             {
     871             :               /* Use that pinentry.  */
     872           0 :               xfree (name);
     873           0 :               name = name2;
     874           0 :               break;
     875             :             }
     876           0 :           if (!i) /* Store the first as fallback return.  */
     877           0 :             name = name2;
     878             :           else
     879           0 :             xfree (name2);
     880             :         }
     881             :     }
     882             : 
     883           0 :   return name;
     884             : }
     885             : 
     886             : 
     887             : /* Return the file name of a helper tool.  WHICH is one of the
     888             :    GNUPG_MODULE_NAME_foo constants.  */
     889             : const char *
     890          48 : gnupg_module_name (int which)
     891             : {
     892             : #define X(a,b) do {                                                     \
     893             :     static char *name;                                                  \
     894             :     if (!name)                                                          \
     895             :       name = xstrconcat (gnupg_ ## a (), DIRSEP_S b EXEEXT_S, NULL);    \
     896             :     return name;                                                        \
     897             :   } while (0)
     898             : 
     899          48 :   switch (which)
     900             :     {
     901             :     case GNUPG_MODULE_NAME_AGENT:
     902             : #ifdef GNUPG_DEFAULT_AGENT
     903             :       return GNUPG_DEFAULT_AGENT;
     904             : #else
     905           0 :       X(bindir, "gpg-agent");
     906             : #endif
     907             : 
     908             :     case GNUPG_MODULE_NAME_PINENTRY:
     909             : #ifdef GNUPG_DEFAULT_PINENTRY
     910             :       return GNUPG_DEFAULT_PINENTRY;  /* (Set by a configure option) */
     911             : #else
     912           0 :       return get_default_pinentry_name (0);
     913             : #endif
     914             : 
     915             :     case GNUPG_MODULE_NAME_SCDAEMON:
     916             : #ifdef GNUPG_DEFAULT_SCDAEMON
     917             :       return GNUPG_DEFAULT_SCDAEMON;
     918             : #else
     919           1 :       X(libexecdir, "scdaemon");
     920             : #endif
     921             : 
     922             :     case GNUPG_MODULE_NAME_DIRMNGR:
     923             : #ifdef GNUPG_DEFAULT_DIRMNGR
     924             :       return GNUPG_DEFAULT_DIRMNGR;
     925             : #else
     926           0 :       X(bindir, DIRMNGR_NAME);
     927             : #endif
     928             : 
     929             :     case GNUPG_MODULE_NAME_PROTECT_TOOL:
     930             : #ifdef GNUPG_DEFAULT_PROTECT_TOOL
     931             :       return GNUPG_DEFAULT_PROTECT_TOOL;
     932             : #else
     933           0 :       X(libexecdir, "gpg-protect-tool");
     934             : #endif
     935             : 
     936             :     case GNUPG_MODULE_NAME_DIRMNGR_LDAP:
     937             : #ifdef GNUPG_DEFAULT_DIRMNGR_LDAP
     938             :       return GNUPG_DEFAULT_DIRMNGR_LDAP;
     939             : #else
     940           0 :       X(libexecdir, "dirmngr_ldap");
     941             : #endif
     942             : 
     943             :     case GNUPG_MODULE_NAME_CHECK_PATTERN:
     944           0 :       X(libexecdir, "gpg-check-pattern");
     945             : 
     946             :     case GNUPG_MODULE_NAME_GPGSM:
     947           0 :       X(bindir, "gpgsm");
     948             : 
     949             :     case GNUPG_MODULE_NAME_GPG:
     950             : #if USE_GPG2_HACK
     951          47 :       X(bindir, GPG_NAME "2");
     952             : #else
     953             :       X(bindir, GPG_NAME);
     954             : #endif
     955             : 
     956             :     case GNUPG_MODULE_NAME_CONNECT_AGENT:
     957           0 :       X(bindir, "gpg-connect-agent");
     958             : 
     959             :     case GNUPG_MODULE_NAME_GPGCONF:
     960           0 :       X(bindir, "gpgconf");
     961             : 
     962             :     default:
     963           0 :       BUG ();
     964             :     }
     965             : #undef X
     966             : }
     967             : 
     968             : 
     969             : /* Flush some of the cached module names.  This is for example used by
     970             :    gpg-agent to allow configuring a different pinentry.  */
     971             : void
     972           0 : gnupg_module_name_flush_some (void)
     973             : {
     974           0 :   (void)get_default_pinentry_name (1);
     975           0 : }

Generated by: LCOV version 1.11