Reworked passing of envars to Pinentry.
[gnupg.git] / common / homedir.c
1 /* homedir.c - Setup the home directory.
2  *      Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <fcntl.h>
24
25 #ifdef HAVE_W32_SYSTEM
26 #include <shlobj.h>
27 #ifndef CSIDL_APPDATA
28 #define CSIDL_APPDATA 0x001a
29 #endif
30 #ifndef CSIDL_LOCAL_APPDATA
31 #define CSIDL_LOCAL_APPDATA 0x001c
32 #endif
33 #ifndef CSIDL_COMMON_APPDATA
34 #define CSIDL_COMMON_APPDATA 0x0023
35 #endif
36 #ifndef CSIDL_FLAG_CREATE
37 #define CSIDL_FLAG_CREATE 0x8000
38 #endif
39 #endif /*HAVE_W32_SYSTEM*/
40
41
42
43 #include "util.h"
44 #include "sysutils.h"
45
46
47 /* This is a helper function to load a Windows function from either of
48    one DLLs. */
49 #ifdef HAVE_W32_SYSTEM
50 static HRESULT
51 w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
52 {
53   static int initialized;
54   static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
55
56   if (!initialized)
57     {
58       static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
59       void *handle;
60       int i;
61
62       initialized = 1;
63
64       for (i=0, handle = NULL; !handle && dllnames[i]; i++)
65         {
66           handle = dlopen (dllnames[i], RTLD_LAZY);
67           if (handle)
68             {
69               func = dlsym (handle, "SHGetFolderPathA");
70               if (!func)
71                 {
72                   dlclose (handle);
73                   handle = NULL;
74                 }
75             }
76         }
77     }
78
79   if (func)
80     return func (a,b,c,d,e);
81   else
82     return -1;
83 }
84 #endif /*HAVE_W32_SYSTEM*/
85
86
87 /* Get the standard home directory.  In general this function should
88    not be used as it does not consider a registry value (under W32) or
89    the GNUPGHOME environment variable.  It is better to use
90    default_homedir(). */
91 const char *
92 standard_homedir (void)
93 {
94 #ifdef HAVE_W32_SYSTEM
95   static const char *dir;
96
97   if (!dir)
98     {
99       char path[MAX_PATH];
100       
101       /* It might be better to use LOCAL_APPDATA because this is
102          defined as "non roaming" and thus more likely to be kept
103          locally.  For private keys this is desired.  However, given
104          that many users copy private keys anyway forth and back,
105          using a system roaming services might be better than to let
106          them do it manually.  A security conscious user will anyway
107          use the registry entry to have better control.  */
108       if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, 
109                                NULL, 0, path) >= 0) 
110         {
111           char *tmp = xmalloc (strlen (path) + 6 +1);
112           strcpy (stpcpy (tmp, path), "\\gnupg");
113           dir = tmp;
114           
115           /* Try to create the directory if it does not yet exists.  */
116           if (access (dir, F_OK))
117             CreateDirectory (dir, NULL);
118         }
119       else
120         dir = GNUPG_DEFAULT_HOMEDIR;
121     }
122   return dir;
123 #else/*!HAVE_W32_SYSTEM*/
124   return GNUPG_DEFAULT_HOMEDIR;
125 #endif /*!HAVE_W32_SYSTEM*/
126 }
127
128 /* Set up the default home directory.  The usual --homedir option
129    should be parsed later. */
130 const char *
131 default_homedir (void)
132 {
133   const char *dir;
134
135   dir = getenv ("GNUPGHOME");
136 #ifdef HAVE_W32_SYSTEM
137   if (!dir || !*dir)
138     {
139       static const char *saved_dir;
140       
141       if (!saved_dir)
142         {
143           if (!dir || !*dir)
144             {
145               char *tmp;
146
147               tmp = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG",
148                                               "HomeDir");
149               if (tmp && !*tmp)
150                 {
151                   xfree (tmp);
152                   tmp = NULL;
153                 }
154               if (tmp)
155                 saved_dir = tmp;
156             }
157           
158           if (!saved_dir)
159             saved_dir = standard_homedir ();
160         }
161       dir = saved_dir;
162     }
163 #endif /*HAVE_W32_SYSTEM*/
164   if (!dir || !*dir)
165     dir = GNUPG_DEFAULT_HOMEDIR;
166
167   return dir;
168 }
169
170
171 #ifdef HAVE_W32_SYSTEM
172 static const char *
173 w32_rootdir (void)
174 {
175   static int got_dir;
176   static char dir[MAX_PATH+5];
177
178   if (!got_dir)
179     {
180       char *p;
181
182       if ( !GetModuleFileName ( NULL, dir, MAX_PATH) )
183         {
184           log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
185           *dir = 0;
186         }
187       got_dir = 1;
188       p = strrchr (dir, DIRSEP_C);
189       if (p)
190         *p = 0;
191       else
192         {
193           log_debug ("bad filename `%s' returned for this process\n", dir);
194           *dir = 0; 
195         }
196     }
197
198   if (*dir)
199     return dir;
200   /* Fallback to the hardwired value. */
201   return GNUPG_LIBEXECDIR;
202 }
203
204 static const char *
205 w32_commondir (void)
206 {
207   static char *dir;
208
209   if (!dir)
210     {
211       char path[MAX_PATH];
212
213       if (w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA, 
214                                NULL, 0, path) >= 0) 
215         {
216           char *tmp = xmalloc (strlen (path) + 4 +1);
217           strcpy (stpcpy (tmp, path), "\\GNU");
218           dir = tmp;
219           /* No auto create of the directory.  Either the installer or
220              the admin has to create these directories.  */
221         }
222       else
223         {
224           /* Ooops: Not defined - probably an old Windows version.
225              Use the installation directory instead.  */
226           dir = xstrdup (w32_rootdir ());
227         }
228     }
229   
230   return dir;
231 }
232 #endif /*HAVE_W32_SYSTEM*/
233
234
235
236
237 /* Return the name of the sysconfdir.  This is a static string.  This
238    function is required because under Windows we can't simply compile
239    it in.  */
240 const char *
241 gnupg_sysconfdir (void)
242 {
243 #ifdef HAVE_W32_SYSTEM
244   static char *name;
245
246   if (!name)
247     {
248       const char *s1, *s2;
249       s1 = w32_commondir ();
250       s2 = DIRSEP_S "etc" DIRSEP_S "gnupg";
251       name = xmalloc (strlen (s1) + strlen (s2) + 1);
252       strcpy (stpcpy (name, s1), s2);
253     }
254   return name;
255 #else /*!HAVE_W32_SYSTEM*/
256   return GNUPG_SYSCONFDIR;
257 #endif /*!HAVE_W32_SYSTEM*/
258 }
259
260
261 const char *
262 gnupg_bindir (void)
263 {
264 #ifdef HAVE_W32_SYSTEM
265   return w32_rootdir ();
266 #else /*!HAVE_W32_SYSTEM*/
267   return GNUPG_BINDIR;
268 #endif /*!HAVE_W32_SYSTEM*/
269 }
270
271
272 /* Return the name of the libexec directory.  The name is allocated in
273    a static area on the first use.  This function won't fail. */
274 const char *
275 gnupg_libexecdir (void)
276 {
277 #ifdef HAVE_W32_SYSTEM
278   return w32_rootdir ();
279 #else /*!HAVE_W32_SYSTEM*/
280   return GNUPG_LIBEXECDIR;
281 #endif /*!HAVE_W32_SYSTEM*/
282 }
283
284 const char *
285 gnupg_libdir (void)
286 {
287 #ifdef HAVE_W32_SYSTEM
288   static char *name;
289
290   if (!name)
291     {
292       const char *s1, *s2;
293       s1 = w32_rootdir ();
294       s2 = DIRSEP_S "lib" DIRSEP_S "gnupg";
295       name = xmalloc (strlen (s1) + strlen (s2) + 1);
296       strcpy (stpcpy (name, s1), s2);
297     }
298   return name;
299 #else /*!HAVE_W32_SYSTEM*/
300   return GNUPG_LIBDIR;
301 #endif /*!HAVE_W32_SYSTEM*/
302 }
303
304 const char *
305 gnupg_datadir (void)
306 {
307 #ifdef HAVE_W32_SYSTEM
308   static char *name;
309
310   if (!name)
311     {
312       const char *s1, *s2;
313       s1 = w32_rootdir ();
314       s2 = DIRSEP_S "share" DIRSEP_S "gnupg";
315       name = xmalloc (strlen (s1) + strlen (s2) + 1);
316       strcpy (stpcpy (name, s1), s2);
317     }
318   return name;
319 #else /*!HAVE_W32_SYSTEM*/
320   return GNUPG_DATADIR;
321 #endif /*!HAVE_W32_SYSTEM*/
322 }
323
324
325 const char *
326 gnupg_localedir (void)
327 {
328 #ifdef HAVE_W32_SYSTEM
329   static char *name;
330
331   if (!name)
332     {
333       const char *s1, *s2;
334       s1 = w32_rootdir ();
335       s2 = DIRSEP_S "share" DIRSEP_S "locale";
336       name = xmalloc (strlen (s1) + strlen (s2) + 1);
337       strcpy (stpcpy (name, s1), s2);
338     }
339   return name;
340 #else /*!HAVE_W32_SYSTEM*/
341   return LOCALEDIR;
342 #endif /*!HAVE_W32_SYSTEM*/
343 }
344
345
346 /* Return the default socket name used by DirMngr. */
347 const char *
348 dirmngr_socket_name (void)
349 {
350 #ifdef HAVE_W32_SYSTEM
351   static char *name;
352
353   if (!name)
354     {
355       char s1[MAX_PATH];
356       const char *s2;
357
358       /* We need something akin CSIDL_COMMON_PROGRAMS, but local
359          (non-roaming).  */
360       if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1) < 0)
361         strcpy (s1, "C:\\WINDOWS");
362       s2 = DIRSEP_S "S.dirmngr";
363       name = xmalloc (strlen (s1) + strlen (s2) + 1);
364       strcpy (stpcpy (name, s1), s2);
365     }
366   return name;
367 #else /*!HAVE_W32_SYSTEM*/
368   return "/var/run/dirmngr/socket";
369 #endif /*!HAVE_W32_SYSTEM*/
370 }
371
372
373
374 /* Return the file name of a helper tool.  WHICH is one of the
375    GNUPG_MODULE_NAME_foo constants.  */
376 const char *
377 gnupg_module_name (int which)
378 {
379   const char *s, *s2;
380
381 #define X(a,b) do {                                          \
382         static char *name;                                   \
383         if (!name)                                           \
384           {                                                  \
385             s = gnupg_ ## a ();                              \
386             s2 = DIRSEP_S b EXEEXT_S;                        \
387             name = xmalloc (strlen (s) + strlen (s2) + 1);   \
388             strcpy (stpcpy (name, s), s2);                   \
389           }                                                  \
390         return name;                                         \
391       } while (0)                                                     
392
393   switch (which)
394     {
395     case GNUPG_MODULE_NAME_AGENT:
396 #ifdef GNUPG_DEFAULT_AGENT
397       return GNUPG_DEFAULT_AGENT;
398 #else 
399       X(bindir, "gpg-agent");
400 #endif
401       
402     case GNUPG_MODULE_NAME_PINENTRY:
403 #ifdef GNUPG_DEFAULT_PINENTRY
404       return GNUPG_DEFAULT_PINENTRY;
405 #else 
406       X(bindir, "pinentry");
407 #endif
408
409     case GNUPG_MODULE_NAME_SCDAEMON:
410 #ifdef GNUPG_DEFAULT_SCDAEMON
411       return GNUPG_DEFAULT_SCDAEMON;
412 #else 
413       X(bindir, "scdaemon");
414 #endif
415
416     case GNUPG_MODULE_NAME_DIRMNGR:
417 #ifdef GNUPG_DEFAULT_DIRMNGR
418       return GNUPG_DEFAULT_DIRMNGR;
419 #else 
420       X(bindir, "dirmngr");
421 #endif
422
423     case GNUPG_MODULE_NAME_PROTECT_TOOL:
424 #ifdef GNUPG_DEFAULT_PROTECT_TOOL
425       return GNUPG_DEFAULT_PROTECT_TOOL;
426 #else 
427       X(libexecdir, "gpg-protect-tool");
428 #endif
429
430     case GNUPG_MODULE_NAME_CHECK_PATTERN:
431       X(libexecdir, "gpg-check-pattern");
432
433     case GNUPG_MODULE_NAME_GPGSM:
434       X(bindir, "gpgsm");
435
436     case GNUPG_MODULE_NAME_GPG:
437       X(bindir, "gpg2");
438
439     case GNUPG_MODULE_NAME_CONNECT_AGENT:
440       X(bindir, "gpg-connect-agent");
441
442     case GNUPG_MODULE_NAME_GPGCONF:
443       X(bindir, "gpgconf");
444
445     default: 
446       BUG ();
447     }
448 #undef X
449 }