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