gpg: Add new compliance mode "de-vs".
[gnupg.git] / common / sysutils.c
1 /* sysutils.c -  system helpers
2  * Copyright (C) 1991-2001, 2003-2004,
3  *               2006-2008  Free Software Foundation, Inc.
4  * Copyright (C) 2013-2014 Werner Koch
5  *
6  * This file is part of GnuPG.
7  *
8  * This file is free software; you can redistribute it and/or modify
9  * it under the terms of either
10  *
11  *   - the GNU Lesser General Public License as published by the Free
12  *     Software Foundation; either version 3 of the License, or (at
13  *     your option) any later version.
14  *
15  * or
16  *
17  *   - the GNU General Public License as published by the Free
18  *     Software Foundation; either version 2 of the License, or (at
19  *     your option) any later version.
20  *
21  * or both in parallel, as here.
22  *
23  * This file is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, see <https://www.gnu.org/licenses/>.
30  */
31
32 #include <config.h>
33
34 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
35 # undef HAVE_NPTH
36 # undef USE_NPTH
37 #endif
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <stdint.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include <errno.h>
45 #ifdef HAVE_STAT
46 # include <sys/stat.h>
47 #endif
48 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
49 # include <asm/sysinfo.h>
50 # include <asm/unistd.h>
51 #endif
52 #include <time.h>
53 #ifdef HAVE_SETRLIMIT
54 # include <sys/time.h>
55 # include <sys/resource.h>
56 #endif
57 #ifdef HAVE_W32_SYSTEM
58 # if WINVER < 0x0500
59 #   define WINVER 0x0500  /* Required for AllowSetForegroundWindow.  */
60 # endif
61 # ifdef HAVE_WINSOCK2_H
62 #  include <winsock2.h>
63 # endif
64 # include <windows.h>
65 #else /*!HAVE_W32_SYSTEM*/
66 # include <sys/socket.h>
67 # include <sys/un.h>
68 #endif
69 #ifdef HAVE_INOTIFY_INIT
70 # include <sys/inotify.h>
71 #endif /*HAVE_INOTIFY_INIT*/
72 #ifdef HAVE_NPTH
73 # include <npth.h>
74 #endif
75 #include <fcntl.h>
76
77 #include <assuan.h>
78
79 #include "util.h"
80 #include "i18n.h"
81
82 #include "sysutils.h"
83
84 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
85
86
87 static GPGRT_INLINE gpg_error_t
88 my_error_from_syserror (void)
89 {
90   return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
91 }
92
93 static GPGRT_INLINE gpg_error_t
94 my_error (int e)
95 {
96   return gpg_err_make (default_errsource, (e));
97 }
98
99
100
101 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
102 #warning using trap_unaligned
103 static int
104 setsysinfo(unsigned long op, void *buffer, unsigned long size,
105                      int *start, void *arg, unsigned long flag)
106 {
107     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
108 }
109
110 void
111 trap_unaligned(void)
112 {
113     unsigned int buf[2];
114
115     buf[0] = SSIN_UACPROC;
116     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
117     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
118 }
119 #else
120 void
121 trap_unaligned(void)
122 {  /* dummy */
123 }
124 #endif
125
126
127 int
128 disable_core_dumps (void)
129 {
130 #ifdef HAVE_DOSISH_SYSTEM
131     return 0;
132 #else
133 # ifdef HAVE_SETRLIMIT
134     struct rlimit limit;
135
136     /* We only set the current limit unless we were not able to
137        retrieve the old value. */
138     if (getrlimit (RLIMIT_CORE, &limit))
139       limit.rlim_max = 0;
140     limit.rlim_cur = 0;
141     if( !setrlimit (RLIMIT_CORE, &limit) )
142         return 0;
143     if( errno != EINVAL && errno != ENOSYS )
144         log_fatal (_("can't disable core dumps: %s\n"), strerror(errno) );
145 #endif
146     return 1;
147 #endif
148 }
149
150 int
151 enable_core_dumps (void)
152 {
153 #ifdef HAVE_DOSISH_SYSTEM
154     return 0;
155 #else
156 # ifdef HAVE_SETRLIMIT
157     struct rlimit limit;
158
159     if (getrlimit (RLIMIT_CORE, &limit))
160       return 1;
161     limit.rlim_cur = limit.rlim_max;
162     setrlimit (RLIMIT_CORE, &limit);
163     return 1; /* We always return true because this function is
164                  merely a debugging aid. */
165 # endif
166     return 1;
167 #endif
168 }
169
170
171
172 /* Return a string which is used as a kind of process ID.  */
173 const byte *
174 get_session_marker (size_t *rlen)
175 {
176   static byte marker[SIZEOF_UNSIGNED_LONG*2];
177   static int initialized;
178
179   if (!initialized)
180     {
181       gcry_create_nonce (marker, sizeof marker);
182       initialized = 1;
183     }
184   *rlen = sizeof (marker);
185   return marker;
186 }
187
188 /* Return a random number in an unsigned int. */
189 unsigned int
190 get_uint_nonce (void)
191 {
192   unsigned int value;
193
194   gcry_create_nonce (&value, sizeof value);
195   return value;
196 }
197
198
199
200 #if 0 /* not yet needed - Note that this will require inclusion of
201          cmacros.am in Makefile.am */
202 int
203 check_permissions(const char *path,int extension,int checkonly)
204 {
205 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
206   char *tmppath;
207   struct stat statbuf;
208   int ret=1;
209   int isdir=0;
210
211   if(opt.no_perm_warn)
212     return 0;
213
214   if(extension && path[0]!=DIRSEP_C)
215     {
216       if(strchr(path,DIRSEP_C))
217         tmppath=make_filename(path,NULL);
218       else
219         tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
220     }
221   else
222     tmppath=m_strdup(path);
223
224   /* It's okay if the file doesn't exist */
225   if(stat(tmppath,&statbuf)!=0)
226     {
227       ret=0;
228       goto end;
229     }
230
231   isdir=S_ISDIR(statbuf.st_mode);
232
233   /* Per-user files must be owned by the user.  Extensions must be
234      owned by the user or root. */
235   if((!extension && statbuf.st_uid != getuid()) ||
236      (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid()))
237     {
238       if(!checkonly)
239         log_info(_("Warning: unsafe ownership on %s \"%s\"\n"),
240                  isdir?"directory":extension?"extension":"file",path);
241       goto end;
242     }
243
244   /* This works for both directories and files - basically, we don't
245      care what the owner permissions are, so long as the group and
246      other permissions are 0 for per-user files, and non-writable for
247      extensions. */
248   if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) ||
249      (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0))
250     {
251       char *dir;
252
253       /* However, if the directory the directory/file is in is owned
254          by the user and is 700, then this is not a problem.
255          Theoretically, we could walk this test up to the root
256          directory /, but for the sake of sanity, I'm stopping at one
257          level down. */
258
259       dir= make_dirname (tmppath);
260       if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() &&
261          S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
262         {
263           xfree (dir);
264           ret=0;
265           goto end;
266         }
267
268       m_free(dir);
269
270       if(!checkonly)
271         log_info(_("Warning: unsafe permissions on %s \"%s\"\n"),
272                  isdir?"directory":extension?"extension":"file",path);
273       goto end;
274     }
275
276   ret=0;
277
278  end:
279   m_free(tmppath);
280
281   return ret;
282
283 #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
284
285   return 0;
286 }
287 #endif
288
289
290 /* Wrapper around the usual sleep function.  This one won't wake up
291    before the sleep time has really elapsed.  When build with Pth it
292    merely calls pth_sleep and thus suspends only the current
293    thread. */
294 void
295 gnupg_sleep (unsigned int seconds)
296 {
297 #ifdef USE_NPTH
298   npth_sleep (seconds);
299 #else
300   /* Fixme:  make sure that a sleep won't wake up to early.  */
301 # ifdef HAVE_W32_SYSTEM
302   Sleep (seconds*1000);
303 # else
304   sleep (seconds);
305 # endif
306 #endif
307 }
308
309
310 /* Wrapper around the platforms usleep function.  This one won't wake
311  * up before the sleep time has really elapsed.  When build with nPth
312  * it merely calls npth_usleep and thus suspends only the current
313  * thread. */
314 void
315 gnupg_usleep (unsigned int usecs)
316 {
317 #if defined(USE_NPTH)
318
319   npth_usleep (usecs);
320
321 #elif defined(HAVE_W32_SYSTEM)
322
323   Sleep ((usecs + 999) / 1000);
324
325 #elif defined(HAVE_NANOSLEEP)
326
327   if (usecs)
328     {
329       struct timespec req;
330       struct timespec rem;
331
332       req.tv_sec = 0;
333       req.tv_nsec = usecs * 1000;
334
335       while (nanosleep (&req, &rem) < 0 && errno == EINTR)
336         req = rem;
337     }
338
339 #else /*Standard Unix*/
340
341   if (usecs)
342     {
343       struct timeval tv;
344
345       tv.tv_sec  = usecs / 1000000;
346       tv.tv_usec = usecs % 1000000;
347       select (0, NULL, NULL, NULL, &tv);
348     }
349
350 #endif
351 }
352
353
354 /* This function is a NOP for POSIX systems but required under Windows
355    as the file handles as returned by OS calls (like CreateFile) are
356    different from the libc file descriptors (like open). This function
357    translates system file handles to libc file handles.  FOR_WRITE
358    gives the direction of the handle.  */
359 int
360 translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
361 {
362 #if defined(HAVE_W32CE_SYSTEM)
363   (void)for_write;
364   return (int) fd;
365 #elif defined(HAVE_W32_SYSTEM)
366   int x;
367
368   if (fd == GNUPG_INVALID_FD)
369     return -1;
370
371   /* Note that _open_osfhandle is currently defined to take and return
372      a long.  */
373   x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
374   if (x == -1)
375     log_error ("failed to translate osfhandle %p\n", (void *) fd);
376   return x;
377 #else /*!HAVE_W32_SYSTEM */
378   (void)for_write;
379   return fd;
380 #endif
381 }
382
383 /* This is the same as translate_sys2libc_fd but takes an integer
384    which is assumed to be such an system handle.  On WindowsCE the
385    passed FD is a rendezvous ID and the function finishes the pipe
386    creation. */
387 int
388 translate_sys2libc_fd_int (int fd, int for_write)
389 {
390 #if HAVE_W32CE_SYSTEM
391   fd = (int) _assuan_w32ce_finish_pipe (fd, for_write);
392   return translate_sys2libc_fd ((void*)fd, for_write);
393 #elif HAVE_W32_SYSTEM
394   if (fd <= 2)
395     return fd;  /* Do not do this for error, stdin, stdout, stderr. */
396
397   return translate_sys2libc_fd ((void*)fd, for_write);
398 #else
399   (void)for_write;
400   return fd;
401 #endif
402 }
403
404
405
406 /* Replacement for tmpfile().  This is required because the tmpfile
407    function of Windows' runtime library is broken, insecure, ignores
408    TMPDIR and so on.  In addition we create a file with an inheritable
409    handle.  */
410 FILE *
411 gnupg_tmpfile (void)
412 {
413 #ifdef HAVE_W32_SYSTEM
414   int attempts, n;
415 #ifdef HAVE_W32CE_SYSTEM
416   wchar_t buffer[MAX_PATH+7+12+1];
417 # define mystrlen(a) wcslen (a)
418   wchar_t *name, *p;
419 #else
420   char buffer[MAX_PATH+7+12+1];
421 # define mystrlen(a) strlen (a)
422   char *name, *p;
423 #endif
424   HANDLE file;
425   int pid = GetCurrentProcessId ();
426   unsigned int value;
427   int i;
428   SECURITY_ATTRIBUTES sec_attr;
429
430   memset (&sec_attr, 0, sizeof sec_attr );
431   sec_attr.nLength = sizeof sec_attr;
432   sec_attr.bInheritHandle = TRUE;
433
434   n = GetTempPath (MAX_PATH+1, buffer);
435   if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH)
436     {
437       gpg_err_set_errno (ENOENT);
438       return NULL;
439     }
440   p = buffer + mystrlen (buffer);
441 #ifdef HAVE_W32CE_SYSTEM
442   wcscpy (p, L"_gnupg");
443   p += 7;
444 #else
445   p = stpcpy (p, "_gnupg");
446 #endif
447   /* We try to create the directory but don't care about an error as
448      it may already exist and the CreateFile would throw an error
449      anyway.  */
450   CreateDirectory (buffer, NULL);
451   *p++ = '\\';
452   name = p;
453   for (attempts=0; attempts < 10; attempts++)
454     {
455       p = name;
456       value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
457       for (i=0; i < 8; i++)
458         {
459           *p++ = tohex (((value >> 28) & 0x0f));
460           value <<= 4;
461         }
462 #ifdef HAVE_W32CE_SYSTEM
463       wcscpy (p, L".tmp");
464 #else
465       strcpy (p, ".tmp");
466 #endif
467       file = CreateFile (buffer,
468                          GENERIC_READ | GENERIC_WRITE,
469                          0,
470                          &sec_attr,
471                          CREATE_NEW,
472                          FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
473                          NULL);
474       if (file != INVALID_HANDLE_VALUE)
475         {
476           FILE *fp;
477 #ifdef HAVE_W32CE_SYSTEM
478           int fd = (int)file;
479           fp = _wfdopen (fd, L"w+b");
480 #else
481           int fd = _open_osfhandle ((long)file, 0);
482           if (fd == -1)
483             {
484               CloseHandle (file);
485               return NULL;
486             }
487           fp = fdopen (fd, "w+b");
488 #endif
489           if (!fp)
490             {
491               int save = errno;
492               close (fd);
493               gpg_err_set_errno (save);
494               return NULL;
495             }
496           return fp;
497         }
498       Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
499     }
500   gpg_err_set_errno (ENOENT);
501   return NULL;
502 #undef mystrlen
503 #else /*!HAVE_W32_SYSTEM*/
504   return tmpfile ();
505 #endif /*!HAVE_W32_SYSTEM*/
506 }
507
508
509 /* Make sure that the standard file descriptors are opened. Obviously
510    some folks close them before an exec and the next file we open will
511    get one of them assigned and thus any output (i.e. diagnostics) end
512    up in that file (e.g. the trustdb).  Not actually a gpg problem as
513    this will happen with almost all utilities when called in a wrong
514    way.  However we try to minimize the damage here and raise
515    awareness of the problem.
516
517    Must be called before we open any files! */
518 void
519 gnupg_reopen_std (const char *pgmname)
520 {
521 #if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
522   struct stat statbuf;
523   int did_stdin = 0;
524   int did_stdout = 0;
525   int did_stderr = 0;
526   FILE *complain;
527
528   if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF)
529     {
530       if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
531         did_stdin = 1;
532       else
533         did_stdin = 2;
534     }
535
536   if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
537     {
538       if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
539         did_stdout = 1;
540       else
541         did_stdout = 2;
542     }
543
544   if (fstat (STDERR_FILENO, &statbuf)==-1 && errno==EBADF)
545     {
546       if (open ("/dev/null", O_WRONLY) == STDERR_FILENO)
547         did_stderr = 1;
548       else
549         did_stderr = 2;
550     }
551
552   /* It's hard to log this sort of thing since the filehandle we would
553      complain to may be closed... */
554   if (!did_stderr)
555     complain = stderr;
556   else if (!did_stdout)
557     complain = stdout;
558   else
559     complain = NULL;
560
561   if (complain)
562     {
563       if (did_stdin == 1)
564         fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname);
565       if (did_stdout == 1)
566         fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname);
567       if (did_stderr == 1)
568         fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname);
569
570       if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
571         fprintf(complain,"%s: fatal: unable to reopen standard input,"
572                 " output, or error\n", pgmname);
573     }
574
575   if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
576     exit (3);
577 #else /* !(HAVE_STAT && !HAVE_W32_SYSTEM) */
578   (void)pgmname;
579 #endif
580 }
581
582
583 /* Hack required for Windows.  */
584 void
585 gnupg_allow_set_foregound_window (pid_t pid)
586 {
587   if (!pid)
588     log_info ("%s called with invalid pid %lu\n",
589               "gnupg_allow_set_foregound_window", (unsigned long)pid);
590 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
591   else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid))
592     log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
593                (unsigned long)pid, w32_strerror (-1));
594 #endif
595 }
596
597 int
598 gnupg_remove (const char *fname)
599 {
600 #ifdef HAVE_W32CE_SYSTEM
601   int rc;
602   wchar_t *wfname;
603
604   wfname = utf8_to_wchar (fname);
605   if (!wfname)
606     rc = 0;
607   else
608     {
609       rc = DeleteFile (wfname);
610       xfree (wfname);
611     }
612   if (!rc)
613     return -1; /* ERRNO is automagically provided by gpg-error.h.  */
614   return 0;
615 #else
616   return remove (fname);
617 #endif
618 }
619
620
621 #ifndef HAVE_W32_SYSTEM
622 static mode_t
623 modestr_to_mode (const char *modestr)
624 {
625   mode_t mode = 0;
626
627   if (modestr && *modestr)
628     {
629       modestr++;
630       if (*modestr && *modestr++ == 'r')
631         mode |= S_IRUSR;
632       if (*modestr && *modestr++ == 'w')
633         mode |= S_IWUSR;
634       if (*modestr && *modestr++ == 'x')
635         mode |= S_IXUSR;
636       if (*modestr && *modestr++ == 'r')
637         mode |= S_IRGRP;
638       if (*modestr && *modestr++ == 'w')
639         mode |= S_IWGRP;
640       if (*modestr && *modestr++ == 'x')
641         mode |= S_IXGRP;
642       if (*modestr && *modestr++ == 'r')
643         mode |= S_IROTH;
644       if (*modestr && *modestr++ == 'w')
645         mode |= S_IWOTH;
646       if (*modestr && *modestr++ == 'x')
647         mode |= S_IXOTH;
648     }
649
650   return mode;
651 }
652 #endif
653
654
655 /* A wrapper around mkdir which takes a string for the mode argument.
656    This makes it easier to handle the mode argument which is not
657    defined on all systems.  The format of the modestring is
658
659       "-rwxrwxrwx"
660
661    '-' is a don't care or not set.  'r', 'w', 'x' are read allowed,
662    write allowed, execution allowed with the first group for the user,
663    the second for the group and the third for all others.  If the
664    string is shorter than above the missing mode characters are meant
665    to be not set.  */
666 int
667 gnupg_mkdir (const char *name, const char *modestr)
668 {
669 #ifdef HAVE_W32CE_SYSTEM
670   wchar_t *wname;
671   (void)modestr;
672
673   wname = utf8_to_wchar (name);
674   if (!wname)
675     return -1;
676   if (!CreateDirectoryW (wname, NULL))
677     {
678       xfree (wname);
679       return -1;  /* ERRNO is automagically provided by gpg-error.h.  */
680     }
681   xfree (wname);
682   return 0;
683 #elif MKDIR_TAKES_ONE_ARG
684   (void)modestr;
685   /* Note: In the case of W32 we better use CreateDirectory and try to
686      set appropriate permissions.  However using mkdir is easier
687      because this sets ERRNO.  */
688   return mkdir (name);
689 #else
690   return mkdir (name, modestr_to_mode (modestr));
691 #endif
692 }
693
694
695 /* A wrapper around chmod which takes a string for the mode argument.
696    This makes it easier to handle the mode argument which is not
697    defined on all systems.  The format of the modestring is the same
698    as for gnupg_mkdir.  */
699 int
700 gnupg_chmod (const char *name, const char *modestr)
701 {
702 #ifdef HAVE_W32_SYSTEM
703   (void)name;
704   (void)modestr;
705   return 0;
706 #else
707   return chmod (name, modestr_to_mode (modestr));
708 #endif
709 }
710
711
712 /* Our version of mkdtemp.  The API is identical to POSIX.1-2008
713    version.  We do not use a system provided mkdtemp because we have a
714    good RNG instantly available and this way we don't have diverging
715    versions.  */
716 char *
717 gnupg_mkdtemp (char *tmpl)
718 {
719   /* A lower bound on the number of temporary files to attempt to
720      generate.  The maximum total number of temporary file names that
721      can exist for a given template is 62**6 (5*36**3 for Windows).
722      It should never be necessary to try all these combinations.
723      Instead if a reasonable number of names is tried (we define
724      reasonable as 62**3 or 5*36**3) fail to give the system
725      administrator the chance to remove the problems.  */
726 #ifdef HAVE_W32_SYSTEM
727   static const char letters[] =
728     "abcdefghijklmnopqrstuvwxyz0123456789";
729 # define NUMBER_OF_LETTERS 36
730 # define ATTEMPTS_MIN (5 * 36 * 36 * 36)
731 #else
732   static const char letters[] =
733     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
734 # define NUMBER_OF_LETTERS 62
735 # define ATTEMPTS_MIN (62 * 62 * 62)
736 #endif
737   int len;
738   char *XXXXXX;
739   uint64_t value;
740   unsigned int count;
741   int save_errno = errno;
742   /* The number of times to attempt to generate a temporary file.  To
743      conform to POSIX, this must be no smaller than TMP_MAX.  */
744 #if ATTEMPTS_MIN < TMP_MAX
745   unsigned int attempts = TMP_MAX;
746 #else
747   unsigned int attempts = ATTEMPTS_MIN;
748 #endif
749
750   len = strlen (tmpl);
751   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
752     {
753       gpg_err_set_errno (EINVAL);
754       return NULL;
755     }
756
757   /* This is where the Xs start.  */
758   XXXXXX = &tmpl[len - 6];
759
760   /* Get a random start value.  */
761   gcry_create_nonce (&value, sizeof value);
762
763   /* Loop until a directory was created.  */
764   for (count = 0; count < attempts; value += 7777, ++count)
765     {
766       uint64_t v = value;
767
768       /* Fill in the random bits.  */
769       XXXXXX[0] = letters[v % NUMBER_OF_LETTERS];
770       v /= NUMBER_OF_LETTERS;
771       XXXXXX[1] = letters[v % NUMBER_OF_LETTERS];
772       v /= NUMBER_OF_LETTERS;
773       XXXXXX[2] = letters[v % NUMBER_OF_LETTERS];
774       v /= NUMBER_OF_LETTERS;
775       XXXXXX[3] = letters[v % NUMBER_OF_LETTERS];
776       v /= NUMBER_OF_LETTERS;
777       XXXXXX[4] = letters[v % NUMBER_OF_LETTERS];
778       v /= NUMBER_OF_LETTERS;
779       XXXXXX[5] = letters[v % NUMBER_OF_LETTERS];
780
781       if (!gnupg_mkdir (tmpl, "-rwx"))
782         {
783           gpg_err_set_errno (save_errno);
784           return tmpl;
785         }
786       if (errno != EEXIST)
787         return NULL;
788     }
789
790   /* We got out of the loop because we ran out of combinations to try.  */
791   gpg_err_set_errno (EEXIST);
792   return NULL;
793 }
794
795
796 int
797 gnupg_setenv (const char *name, const char *value, int overwrite)
798 {
799 #ifdef HAVE_W32CE_SYSTEM
800   (void)name;
801   (void)value;
802   (void)overwrite;
803   return 0;
804 #else /*!W32CE*/
805 # ifdef HAVE_W32_SYSTEM
806   /*  Windows maintains (at least) two sets of environment variables.
807       One set can be accessed by GetEnvironmentVariable and
808       SetEnvironmentVariable.  This set is inherited by the children.
809       The other set is maintained in the C runtime, and is accessed
810       using getenv and putenv.  We try to keep them in sync by
811       modifying both sets.  */
812   {
813     int exists;
814     char tmpbuf[10];
815     exists = GetEnvironmentVariable (name, tmpbuf, sizeof tmpbuf);
816
817     if ((! exists || overwrite) && !SetEnvironmentVariable (name, value))
818       {
819         gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
820         return -1;
821       }
822   }
823 # endif /*W32*/
824
825 # ifdef HAVE_SETENV
826   return setenv (name, value, overwrite);
827 # else /*!HAVE_SETENV*/
828   if (! getenv (name) || overwrite)
829     {
830       char *buf;
831
832       (void)overwrite;
833       if (!name || !value)
834         {
835           gpg_err_set_errno (EINVAL);
836           return -1;
837         }
838       buf = strconcat (name, "=", value, NULL);
839       if (!buf)
840         return -1;
841 # if __GNUC__
842 #  warning no setenv - using putenv but leaking memory.
843 # endif
844       return putenv (buf);
845     }
846   return 0;
847 # endif /*!HAVE_SETENV*/
848 #endif /*!W32CE*/
849 }
850
851
852 int
853 gnupg_unsetenv (const char *name)
854 {
855 #ifdef HAVE_W32CE_SYSTEM
856   (void)name;
857   return 0;
858 #else /*!W32CE*/
859 # ifdef HAVE_W32_SYSTEM
860   /*  Windows maintains (at least) two sets of environment variables.
861       One set can be accessed by GetEnvironmentVariable and
862       SetEnvironmentVariable.  This set is inherited by the children.
863       The other set is maintained in the C runtime, and is accessed
864       using getenv and putenv.  We try to keep them in sync by
865       modifying both sets.  */
866   if (!SetEnvironmentVariable (name, NULL))
867     {
868       gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
869       return -1;
870     }
871 # endif /*W32*/
872
873 # ifdef HAVE_UNSETENV
874   return unsetenv (name);
875 # else /*!HAVE_UNSETENV*/
876   {
877     char *buf;
878
879     if (!name)
880       {
881         gpg_err_set_errno (EINVAL);
882         return -1;
883       }
884     buf = xtrystrdup (name);
885     if (!buf)
886       return -1;
887 #  if __GNUC__
888 #   warning no unsetenv - trying putenv but leaking memory.
889 #  endif
890     return putenv (buf);
891   }
892 # endif /*!HAVE_UNSETENV*/
893 #endif /*!W32CE*/
894 }
895
896
897 /* Return the current working directory as a malloced string.  Return
898    NULL and sets ERRNo on error.  */
899 char *
900 gnupg_getcwd (void)
901 {
902   char *buffer;
903   size_t size = 100;
904
905   for (;;)
906     {
907       buffer = xtrymalloc (size+1);
908       if (!buffer)
909         return NULL;
910 #ifdef HAVE_W32CE_SYSTEM
911       strcpy (buffer, "/");  /* Always "/".  */
912       return buffer;
913 #else
914       if (getcwd (buffer, size) == buffer)
915         return buffer;
916       xfree (buffer);
917       if (errno != ERANGE)
918         return NULL;
919       size *= 2;
920 #endif
921     }
922 }
923
924
925 \f
926 #ifdef HAVE_W32CE_SYSTEM
927 /* There is a isatty function declaration in cegcc but it does not
928    make sense, thus we redefine it.  */
929 int
930 _gnupg_isatty (int fd)
931 {
932   (void)fd;
933   return 0;
934 }
935 #endif
936
937
938 #ifdef HAVE_W32CE_SYSTEM
939 /* Replacement for getenv which takes care of the our use of getenv.
940    The code is not thread safe but we expect it to work in all cases
941    because it is called for the first time early enough.  */
942 char *
943 _gnupg_getenv (const char *name)
944 {
945   static int initialized;
946   static char *assuan_debug;
947
948   if (!initialized)
949     {
950       assuan_debug = read_w32_registry_string (NULL,
951                                                "\\Software\\GNU\\libassuan",
952                                                "debug");
953       initialized = 1;
954     }
955
956   if (!strcmp (name, "ASSUAN_DEBUG"))
957     return assuan_debug;
958   else
959     return NULL;
960 }
961
962 #endif /*HAVE_W32CE_SYSTEM*/
963
964
965 #ifdef HAVE_W32_SYSTEM
966 /* Return the user's security identifier from the current process.  */
967 PSID
968 w32_get_user_sid (void)
969 {
970   int okay = 0;
971   HANDLE proc = NULL;
972   HANDLE token = NULL;
973   TOKEN_USER *user = NULL;
974   PSID sid = NULL;
975   DWORD tokenlen, sidlen;
976
977   proc = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
978   if (!proc)
979     goto leave;
980
981   if (!OpenProcessToken (proc, TOKEN_QUERY, &token))
982     goto leave;
983
984   if (!GetTokenInformation (token, TokenUser, NULL, 0, &tokenlen)
985       && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
986     goto leave;
987
988   user = xtrymalloc (tokenlen);
989   if (!user)
990     goto leave;
991
992   if (!GetTokenInformation (token, TokenUser, user, tokenlen, &tokenlen))
993     goto leave;
994   if (!IsValidSid (user->User.Sid))
995     goto leave;
996   sidlen = GetLengthSid (user->User.Sid);
997   sid = xtrymalloc (sidlen);
998   if (!sid)
999     goto leave;
1000   if (!CopySid (sidlen, sid, user->User.Sid))
1001     goto leave;
1002   okay = 1;
1003
1004  leave:
1005   xfree (user);
1006   if (token)
1007     CloseHandle (token);
1008   if (proc)
1009     CloseHandle (proc);
1010
1011   if (!okay)
1012     {
1013       xfree (sid);
1014       sid = NULL;
1015     }
1016   return sid;
1017 }
1018 #endif /*HAVE_W32_SYSTEM*/
1019
1020
1021 \f
1022 /* Support for inotify under Linux.  */
1023
1024 /* Store a new inotify file handle for SOCKET_NAME at R_FD or return
1025  * an error code. */
1026 gpg_error_t
1027 gnupg_inotify_watch_socket (int *r_fd, const char *socket_name)
1028 {
1029 #if HAVE_INOTIFY_INIT
1030   gpg_error_t err;
1031   char *fname;
1032   int fd;
1033   char *p;
1034
1035   *r_fd = -1;
1036
1037   if (!socket_name)
1038     return my_error (GPG_ERR_INV_VALUE);
1039
1040   fname = xtrystrdup (socket_name);
1041   if (!fname)
1042     return my_error_from_syserror ();
1043
1044   fd = inotify_init ();
1045   if (fd == -1)
1046     {
1047       err = my_error_from_syserror ();
1048       xfree (fname);
1049       return err;
1050     }
1051
1052   /* We need to watch the directory for the file because there won't
1053    * be an IN_DELETE_SELF for a socket file.  To handle a removal of
1054    * the directory we also watch the directory itself. */
1055   p = strrchr (fname, '/');
1056   if (p)
1057     *p = 0;
1058   if (inotify_add_watch (fd, fname,
1059                          (IN_DELETE|IN_DELETE_SELF|IN_EXCL_UNLINK)) == -1)
1060     {
1061       err = my_error_from_syserror ();
1062       close (fd);
1063       xfree (fname);
1064       return err;
1065     }
1066
1067   xfree (fname);
1068
1069   *r_fd = fd;
1070   return 0;
1071 #else /*!HAVE_INOTIFY_INIT*/
1072
1073   (void)socket_name;
1074   *r_fd = -1;
1075   return my_error (GPG_ERR_NOT_SUPPORTED);
1076
1077 #endif /*!HAVE_INOTIFY_INIT*/
1078 }
1079
1080
1081 /* Read an inotify event and return true if it matches NAME or if it
1082  * sees an IN_DELETE_SELF event for the directory of NAME.  */
1083 int
1084 gnupg_inotify_has_name (int fd, const char *name)
1085 {
1086 #if USE_NPTH && HAVE_INOTIFY_INIT
1087 #define BUFSIZE_FOR_INOTIFY (sizeof (struct inotify_event) + 255 + 1)
1088   union {
1089     struct inotify_event ev;
1090     char _buf[sizeof (struct inotify_event) + 255 + 1];
1091   } buf;
1092   struct inotify_event *evp;
1093   int n;
1094
1095   n = npth_read (fd, &buf, sizeof buf);
1096   /* log_debug ("notify read: n=%d\n", n); */
1097   evp = &buf.ev;
1098   while (n >= sizeof (struct inotify_event))
1099     {
1100       /* log_debug ("             mask=%x len=%u name=(%s)\n", */
1101       /*        evp->mask, (unsigned int)evp->len, evp->len? evp->name:""); */
1102       if ((evp->mask & IN_UNMOUNT))
1103         {
1104           /* log_debug ("             found (dir unmounted)\n"); */
1105           return 3; /* Directory was unmounted.  */
1106         }
1107       if ((evp->mask & IN_DELETE_SELF))
1108         {
1109           /* log_debug ("             found (dir removed)\n"); */
1110           return 2; /* Directory was removed.  */
1111         }
1112       if ((evp->mask & IN_DELETE))
1113         {
1114           if (evp->len >= strlen (name) && !strcmp (evp->name, name))
1115             {
1116               /* log_debug ("             found (file removed)\n"); */
1117               return 1; /* File was removed.  */
1118             }
1119         }
1120       n -= sizeof (*evp) + evp->len;
1121       evp = (struct inotify_event *)(void *)
1122         ((char *)evp + sizeof (*evp) + evp->len);
1123     }
1124
1125 #else /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
1126
1127   (void)fd;
1128   (void)name;
1129
1130 #endif  /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
1131
1132   return 0; /* Not found.  */
1133 }
1134
1135
1136 /* Return a malloc'ed string that is the path to the passed
1137  * unix-domain socket (or return NULL if this is not a valid
1138  * unix-domain socket).  We use a plain int here because it is only
1139  * used on Linux.
1140  *
1141  * FIXME: This function needs to be moved to libassuan.  */
1142 #ifndef HAVE_W32_SYSTEM
1143 char *
1144 gnupg_get_socket_name (int fd)
1145 {
1146   struct sockaddr_un un;
1147   socklen_t len = sizeof(un);
1148   char *name = NULL;
1149
1150   if (getsockname (fd, (struct sockaddr*)&un, &len) != 0)
1151     log_error ("could not getsockname(%d): %s\n", fd,
1152                gpg_strerror (my_error_from_syserror ()));
1153   else if (un.sun_family != AF_UNIX)
1154     log_error ("file descriptor %d is not a unix-domain socket\n", fd);
1155   else if (len <= offsetof (struct sockaddr_un, sun_path))
1156     log_error ("socket name not present for file descriptor %d\n", fd);
1157   else if (len > sizeof(un))
1158     log_error ("socket name for file descriptor %d was truncated "
1159                "(passed %zu bytes, wanted %u)\n", fd, sizeof(un), len);
1160   else
1161     {
1162       size_t namelen = len - offsetof (struct sockaddr_un, sun_path);
1163
1164       /* log_debug ("file descriptor %d has path %s (%zu octets)\n", fd, */
1165       /*            un.sun_path, namelen); */
1166       name = xtrymalloc (namelen + 1);
1167       if (!name)
1168         log_error ("failed to allocate memory for name of fd %d: %s\n",
1169                    fd, gpg_strerror (my_error_from_syserror ()));
1170       else
1171         {
1172           memcpy (name, un.sun_path, namelen);
1173           name[namelen] = 0;
1174         }
1175     }
1176
1177   return name;
1178 }
1179 #endif /*!HAVE_W32_SYSTEM*/