More work on the dirmngr. It now builds for W32 and W32CE and quick
[gnupg.git] / common / homedir.c
1 /* homedir.c - Setup the home directory.
2  * Copyright (C) 2004, 2006, 2007, 2010 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 #ifdef HAVE_W32_SYSTEM
48 static void
49 w32_try_mkdir (const char *dir)
50 {
51 #ifdef HAVE_W32CE_SYSTEM
52   wchar_t *wdir = utf8_to_wchar (dir);
53   if (wdir)
54     {
55       CreateDirectory (wdir, NULL);
56       xfree (wdir);
57     }
58 #else              
59   CreateDirectory (dir, NULL);
60 #endif
61 }
62 #endif
63
64
65 /* This is a helper function to load a Windows function from either of
66    one DLLs. */
67 #ifdef HAVE_W32_SYSTEM
68 static HRESULT
69 w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
70 {
71   static int initialized;
72   static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
73
74   if (!initialized)
75     {
76       static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
77       void *handle;
78       int i;
79
80       initialized = 1;
81
82       for (i=0, handle = NULL; !handle && dllnames[i]; i++)
83         {
84           handle = dlopen (dllnames[i], RTLD_LAZY);
85           if (handle)
86             {
87               func = dlsym (handle, "SHGetFolderPathA");
88               if (!func)
89                 {
90                   dlclose (handle);
91                   handle = NULL;
92                 }
93             }
94         }
95     }
96
97   if (func)
98     return func (a,b,c,d,e);
99   else
100     return -1;
101 }
102 #endif /*HAVE_W32_SYSTEM*/
103
104
105 /* Get the standard home directory.  In general this function should
106    not be used as it does not consider a registry value (under W32) or
107    the GNUPGHOME environment variable.  It is better to use
108    default_homedir(). */
109 const char *
110 standard_homedir (void)
111 {
112 #ifdef HAVE_W32_SYSTEM
113   static const char *dir;
114
115   if (!dir)
116     {
117       char path[MAX_PATH];
118       
119       /* It might be better to use LOCAL_APPDATA because this is
120          defined as "non roaming" and thus more likely to be kept
121          locally.  For private keys this is desired.  However, given
122          that many users copy private keys anyway forth and back,
123          using a system roaming services might be better than to let
124          them do it manually.  A security conscious user will anyway
125          use the registry entry to have better control.  */
126       if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, 
127                                NULL, 0, path) >= 0) 
128         {
129           char *tmp = xmalloc (strlen (path) + 6 +1);
130           strcpy (stpcpy (tmp, path), "\\gnupg");
131           dir = tmp;
132           
133           /* Try to create the directory if it does not yet exists.  */
134           if (access (dir, F_OK))
135             w32_try_mkdir (dir);
136         }
137       else
138         dir = GNUPG_DEFAULT_HOMEDIR;
139     }
140   return dir;
141 #else/*!HAVE_W32_SYSTEM*/
142   return GNUPG_DEFAULT_HOMEDIR;
143 #endif /*!HAVE_W32_SYSTEM*/
144 }
145
146 /* Set up the default home directory.  The usual --homedir option
147    should be parsed later. */
148 const char *
149 default_homedir (void)
150 {
151   const char *dir;
152
153   dir = getenv ("GNUPGHOME");
154 #ifdef HAVE_W32_SYSTEM
155   if (!dir || !*dir)
156     {
157       static const char *saved_dir;
158       
159       if (!saved_dir)
160         {
161           if (!dir || !*dir)
162             {
163               char *tmp;
164
165               tmp = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG",
166                                               "HomeDir");
167               if (tmp && !*tmp)
168                 {
169                   xfree (tmp);
170                   tmp = NULL;
171                 }
172               if (tmp)
173                 saved_dir = tmp;
174             }
175           
176           if (!saved_dir)
177             saved_dir = standard_homedir ();
178         }
179       dir = saved_dir;
180     }
181 #endif /*HAVE_W32_SYSTEM*/
182   if (!dir || !*dir)
183     dir = GNUPG_DEFAULT_HOMEDIR;
184
185   return dir;
186 }
187
188
189 #ifdef HAVE_W32_SYSTEM
190 static const char *
191 w32_rootdir (void)
192 {
193   static int got_dir;
194   static char dir[MAX_PATH+5];
195
196   if (!got_dir)
197     {
198       char *p;
199       int rc;
200
201 #ifdef HAVE_W32CE_SYSTEM
202       {
203         wchar_t wdir [MAX_PATH+5];
204         rc = GetModuleFileName (NULL, wdir, MAX_PATH);
205         if (rc && WideCharToMultiByte (CP_UTF8, 0, wdir, -1, dir, MAX_PATH-4,
206                                        NULL, NULL) < 0)
207           rc = 0;
208       }
209 #else
210       rc = GetModuleFileName (NULL, dir, MAX_PATH);
211 #endif
212       if (!rc)
213         {
214           log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
215           *dir = 0;
216         }
217       got_dir = 1;
218       p = strrchr (dir, DIRSEP_C);
219       if (p)
220         *p = 0;
221       else
222         {
223           log_debug ("bad filename `%s' returned for this process\n", dir);
224           *dir = 0; 
225         }
226     }
227
228   if (*dir)
229     return dir;
230   /* Fallback to the hardwired value. */
231   return GNUPG_LIBEXECDIR;
232 }
233
234 static const char *
235 w32_commondir (void)
236 {
237   static char *dir;
238
239   if (!dir)
240     {
241       char path[MAX_PATH];
242
243       if (w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA, 
244                                NULL, 0, path) >= 0) 
245         {
246           char *tmp = xmalloc (strlen (path) + 4 +1);
247           strcpy (stpcpy (tmp, path), "\\GNU");
248           dir = tmp;
249           /* No auto create of the directory.  Either the installer or
250              the admin has to create these directories.  */
251         }
252       else
253         {
254           /* Ooops: Not defined - probably an old Windows version.
255              Use the installation directory instead.  */
256           dir = xstrdup (w32_rootdir ());
257         }
258     }
259   
260   return dir;
261 }
262 #endif /*HAVE_W32_SYSTEM*/
263
264
265
266
267 /* Return the name of the sysconfdir.  This is a static string.  This
268    function is required because under Windows we can't simply compile
269    it in.  */
270 const char *
271 gnupg_sysconfdir (void)
272 {
273 #ifdef HAVE_W32_SYSTEM
274   static char *name;
275
276   if (!name)
277     {
278       const char *s1, *s2;
279       s1 = w32_commondir ();
280       s2 = DIRSEP_S "etc" DIRSEP_S "gnupg";
281       name = xmalloc (strlen (s1) + strlen (s2) + 1);
282       strcpy (stpcpy (name, s1), s2);
283     }
284   return name;
285 #else /*!HAVE_W32_SYSTEM*/
286   return GNUPG_SYSCONFDIR;
287 #endif /*!HAVE_W32_SYSTEM*/
288 }
289
290
291 const char *
292 gnupg_bindir (void)
293 {
294 #ifdef HAVE_W32_SYSTEM
295   return w32_rootdir ();
296 #else /*!HAVE_W32_SYSTEM*/
297   return GNUPG_BINDIR;
298 #endif /*!HAVE_W32_SYSTEM*/
299 }
300
301
302 /* Return the name of the libexec directory.  The name is allocated in
303    a static area on the first use.  This function won't fail. */
304 const char *
305 gnupg_libexecdir (void)
306 {
307 #ifdef HAVE_W32_SYSTEM
308   return w32_rootdir ();
309 #else /*!HAVE_W32_SYSTEM*/
310   return GNUPG_LIBEXECDIR;
311 #endif /*!HAVE_W32_SYSTEM*/
312 }
313
314 const char *
315 gnupg_libdir (void)
316 {
317 #ifdef HAVE_W32_SYSTEM
318   static char *name;
319
320   if (!name)
321     {
322       const char *s1, *s2;
323       s1 = w32_rootdir ();
324       s2 = DIRSEP_S "lib" DIRSEP_S "gnupg";
325       name = xmalloc (strlen (s1) + strlen (s2) + 1);
326       strcpy (stpcpy (name, s1), s2);
327     }
328   return name;
329 #else /*!HAVE_W32_SYSTEM*/
330   return GNUPG_LIBDIR;
331 #endif /*!HAVE_W32_SYSTEM*/
332 }
333
334 const char *
335 gnupg_datadir (void)
336 {
337 #ifdef HAVE_W32_SYSTEM
338   static char *name;
339
340   if (!name)
341     {
342       const char *s1, *s2;
343       s1 = w32_rootdir ();
344       s2 = DIRSEP_S "share" DIRSEP_S "gnupg";
345       name = xmalloc (strlen (s1) + strlen (s2) + 1);
346       strcpy (stpcpy (name, s1), s2);
347     }
348   return name;
349 #else /*!HAVE_W32_SYSTEM*/
350   return GNUPG_DATADIR;
351 #endif /*!HAVE_W32_SYSTEM*/
352 }
353
354
355 const char *
356 gnupg_localedir (void)
357 {
358 #ifdef HAVE_W32_SYSTEM
359   static char *name;
360
361   if (!name)
362     {
363       const char *s1, *s2;
364       s1 = w32_rootdir ();
365       s2 = DIRSEP_S "share" DIRSEP_S "locale";
366       name = xmalloc (strlen (s1) + strlen (s2) + 1);
367       strcpy (stpcpy (name, s1), s2);
368     }
369   return name;
370 #else /*!HAVE_W32_SYSTEM*/
371   return LOCALEDIR;
372 #endif /*!HAVE_W32_SYSTEM*/
373 }
374
375
376 /* Return the name of the cache directory.  The name is allocated in a
377    static area on the first use.  Windows only: If the directory does
378    not exist it is created.  */
379 const char *
380 gnupg_cachedir (void)
381 {
382 #ifdef HAVE_W32_SYSTEM
383   static const char *dir;
384
385   if (!dir)
386     {
387       char path[MAX_PATH];
388       const char *s1[] = { "GNU", "cache", "gnupg", NULL };
389       int s1_len;
390       const char **comp;
391
392       s1_len = 0;
393       for (comp = s1; *comp; comp++)
394         s1_len += 1 + strlen (*comp);
395
396       if (w32_shgetfolderpath (NULL, CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE, 
397                                NULL, 0, path) >= 0) 
398         {
399           char *tmp = xmalloc (strlen (path) + s1_len + 1);
400           char *p;
401
402           p = stpcpy (tmp, path);
403           for (comp = s1; *comp; comp++)
404             {
405               p = stpcpy (p, "\\");
406               p = stpcpy (p, *comp);
407
408               if (access (tmp, F_OK))
409                 w32_try_mkdir (tmp);
410             }
411
412           dir = tmp;
413         }
414       else
415         {
416           dir = "c:\\temp\\cache\\gnupg";
417 #ifdef HAVE_W32CE_SYSTEM
418           dir += 2;
419 #endif
420         }
421     }
422   return dir;
423 #else /*!HAVE_W32_SYSTEM*/
424   return GNUPG_LOCALSTATEDIR "/cache/" PACKAGE_NAME;
425 #endif /*!HAVE_W32_SYSTEM*/
426 }
427
428
429 /* Return the default socket name used by DirMngr. */
430 const char *
431 dirmngr_socket_name (void)
432 {
433 #ifdef HAVE_W32_SYSTEM
434   static char *name;
435
436   if (!name)
437     {
438       char *p;
439 # ifdef HAVE_W32CE_SYSTEM
440       const char *s1, *s2;
441
442       s1 = default_homedir ();
443 # else
444       char s1[MAX_PATH];
445       const char *s2;
446
447       /* We need something akin CSIDL_COMMON_PROGRAMS, but local
448          (non-roaming).  This is becuase the file needs to be on the
449          local machine and makes only sense on that machine.
450          CSIDL_WINDOWS seems to be the only location which guarantees
451          that. */
452       if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1) < 0)
453         strcpy (s1, "C:\\WINDOWS");
454 # endif
455       s2 = DIRSEP_S "S.dirmngr";
456       name = xmalloc (strlen (s1) + strlen (s2) + 1);
457       strcpy (stpcpy (name, s1), s2);
458       for (p=name; *p; p++)
459         if (*p == '/')
460           *p = '\\';
461     }
462   return name;
463 #else /*!HAVE_W32_SYSTEM*/
464   return GNUPG_LOCALSTATEDIR "/run/" PACKAGE_NAME "/S.dirmngr";
465 #endif /*!HAVE_W32_SYSTEM*/
466 }
467
468
469
470 /* Return the file name of a helper tool.  WHICH is one of the
471    GNUPG_MODULE_NAME_foo constants.  */
472 const char *
473 gnupg_module_name (int which)
474 {
475   const char *s, *s2;
476
477 #define X(a,b) do {                                          \
478         static char *name;                                   \
479         if (!name)                                           \
480           {                                                  \
481             s = gnupg_ ## a ();                              \
482             s2 = DIRSEP_S b EXEEXT_S;                        \
483             name = xmalloc (strlen (s) + strlen (s2) + 1);   \
484             strcpy (stpcpy (name, s), s2);                   \
485           }                                                  \
486         return name;                                         \
487       } while (0)                                                     
488
489   switch (which)
490     {
491     case GNUPG_MODULE_NAME_AGENT:
492 #ifdef GNUPG_DEFAULT_AGENT
493       return GNUPG_DEFAULT_AGENT;
494 #else 
495       X(bindir, "gpg-agent");
496 #endif
497       
498     case GNUPG_MODULE_NAME_PINENTRY:
499 #ifdef GNUPG_DEFAULT_PINENTRY
500       return GNUPG_DEFAULT_PINENTRY;
501 #else 
502       X(bindir, "pinentry");
503 #endif
504
505     case GNUPG_MODULE_NAME_SCDAEMON:
506 #ifdef GNUPG_DEFAULT_SCDAEMON
507       return GNUPG_DEFAULT_SCDAEMON;
508 #else 
509       X(bindir, "scdaemon");
510 #endif
511
512     case GNUPG_MODULE_NAME_DIRMNGR:
513 #ifdef GNUPG_DEFAULT_DIRMNGR
514       return GNUPG_DEFAULT_DIRMNGR;
515 #else 
516       X(bindir, "dirmngr");
517 #endif
518
519     case GNUPG_MODULE_NAME_PROTECT_TOOL:
520 #ifdef GNUPG_DEFAULT_PROTECT_TOOL
521       return GNUPG_DEFAULT_PROTECT_TOOL;
522 #else 
523       X(libexecdir, "gpg-protect-tool");
524 #endif
525
526     case GNUPG_MODULE_NAME_DIRMNGR_LDAP:
527 #ifdef GNUPG_DEFAULT_DIRMNGR_LDAP
528       return GNUPG_DEFAULT_DIRMNGR_LDAP;
529 #else 
530       X(libexecdir, "dirmngr_ldap");
531 #endif
532
533     case GNUPG_MODULE_NAME_CHECK_PATTERN:
534       X(libexecdir, "gpg-check-pattern");
535
536     case GNUPG_MODULE_NAME_GPGSM:
537       X(bindir, "gpgsm");
538
539     case GNUPG_MODULE_NAME_GPG:
540       X(bindir, "gpg2");
541
542     case GNUPG_MODULE_NAME_CONNECT_AGENT:
543       X(bindir, "gpg-connect-agent");
544
545     case GNUPG_MODULE_NAME_GPGCONF:
546       X(bindir, "gpgconf");
547
548     default: 
549       BUG ();
550     }
551 #undef X
552 }