common: Remove debug output from gnupg_get_socket_name.
[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 <http://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 #ifdef HAVE_SETRLIMIT
53 # include <time.h>
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 /* This function is a NOP for POSIX systems but required under Windows
311    as the file handles as returned by OS calls (like CreateFile) are
312    different from the libc file descriptors (like open). This function
313    translates system file handles to libc file handles.  FOR_WRITE
314    gives the direction of the handle.  */
315 int
316 translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
317 {
318 #if defined(HAVE_W32CE_SYSTEM)
319   (void)for_write;
320   return (int) fd;
321 #elif defined(HAVE_W32_SYSTEM)
322   int x;
323
324   if (fd == GNUPG_INVALID_FD)
325     return -1;
326
327   /* Note that _open_osfhandle is currently defined to take and return
328      a long.  */
329   x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
330   if (x == -1)
331     log_error ("failed to translate osfhandle %p\n", (void *) fd);
332   return x;
333 #else /*!HAVE_W32_SYSTEM */
334   (void)for_write;
335   return fd;
336 #endif
337 }
338
339 /* This is the same as translate_sys2libc_fd but takes an integer
340    which is assumed to be such an system handle.  On WindowsCE the
341    passed FD is a rendezvous ID and the function finishes the pipe
342    creation. */
343 int
344 translate_sys2libc_fd_int (int fd, int for_write)
345 {
346 #if HAVE_W32CE_SYSTEM
347   fd = (int) _assuan_w32ce_finish_pipe (fd, for_write);
348   return translate_sys2libc_fd ((void*)fd, for_write);
349 #elif HAVE_W32_SYSTEM
350   if (fd <= 2)
351     return fd;  /* Do not do this for error, stdin, stdout, stderr. */
352
353   return translate_sys2libc_fd ((void*)fd, for_write);
354 #else
355   (void)for_write;
356   return fd;
357 #endif
358 }
359
360
361
362 /* Replacement for tmpfile().  This is required because the tmpfile
363    function of Windows' runtime library is broken, insecure, ignores
364    TMPDIR and so on.  In addition we create a file with an inheritable
365    handle.  */
366 FILE *
367 gnupg_tmpfile (void)
368 {
369 #ifdef HAVE_W32_SYSTEM
370   int attempts, n;
371 #ifdef HAVE_W32CE_SYSTEM
372   wchar_t buffer[MAX_PATH+7+12+1];
373 # define mystrlen(a) wcslen (a)
374   wchar_t *name, *p;
375 #else
376   char buffer[MAX_PATH+7+12+1];
377 # define mystrlen(a) strlen (a)
378   char *name, *p;
379 #endif
380   HANDLE file;
381   int pid = GetCurrentProcessId ();
382   unsigned int value;
383   int i;
384   SECURITY_ATTRIBUTES sec_attr;
385
386   memset (&sec_attr, 0, sizeof sec_attr );
387   sec_attr.nLength = sizeof sec_attr;
388   sec_attr.bInheritHandle = TRUE;
389
390   n = GetTempPath (MAX_PATH+1, buffer);
391   if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH)
392     {
393       gpg_err_set_errno (ENOENT);
394       return NULL;
395     }
396   p = buffer + mystrlen (buffer);
397 #ifdef HAVE_W32CE_SYSTEM
398   wcscpy (p, L"_gnupg");
399   p += 7;
400 #else
401   p = stpcpy (p, "_gnupg");
402 #endif
403   /* We try to create the directory but don't care about an error as
404      it may already exist and the CreateFile would throw an error
405      anyway.  */
406   CreateDirectory (buffer, NULL);
407   *p++ = '\\';
408   name = p;
409   for (attempts=0; attempts < 10; attempts++)
410     {
411       p = name;
412       value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
413       for (i=0; i < 8; i++)
414         {
415           *p++ = tohex (((value >> 28) & 0x0f));
416           value <<= 4;
417         }
418 #ifdef HAVE_W32CE_SYSTEM
419       wcscpy (p, L".tmp");
420 #else
421       strcpy (p, ".tmp");
422 #endif
423       file = CreateFile (buffer,
424                          GENERIC_READ | GENERIC_WRITE,
425                          0,
426                          &sec_attr,
427                          CREATE_NEW,
428                          FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
429                          NULL);
430       if (file != INVALID_HANDLE_VALUE)
431         {
432           FILE *fp;
433 #ifdef HAVE_W32CE_SYSTEM
434           int fd = (int)file;
435           fp = _wfdopen (fd, L"w+b");
436 #else
437           int fd = _open_osfhandle ((long)file, 0);
438           if (fd == -1)
439             {
440               CloseHandle (file);
441               return NULL;
442             }
443           fp = fdopen (fd, "w+b");
444 #endif
445           if (!fp)
446             {
447               int save = errno;
448               close (fd);
449               gpg_err_set_errno (save);
450               return NULL;
451             }
452           return fp;
453         }
454       Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
455     }
456   gpg_err_set_errno (ENOENT);
457   return NULL;
458 #undef mystrlen
459 #else /*!HAVE_W32_SYSTEM*/
460   return tmpfile ();
461 #endif /*!HAVE_W32_SYSTEM*/
462 }
463
464
465 /* Make sure that the standard file descriptors are opened. Obviously
466    some folks close them before an exec and the next file we open will
467    get one of them assigned and thus any output (i.e. diagnostics) end
468    up in that file (e.g. the trustdb).  Not actually a gpg problem as
469    this will happen with almost all utilities when called in a wrong
470    way.  However we try to minimize the damage here and raise
471    awareness of the problem.
472
473    Must be called before we open any files! */
474 void
475 gnupg_reopen_std (const char *pgmname)
476 {
477 #if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
478   struct stat statbuf;
479   int did_stdin = 0;
480   int did_stdout = 0;
481   int did_stderr = 0;
482   FILE *complain;
483
484   if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF)
485     {
486       if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
487         did_stdin = 1;
488       else
489         did_stdin = 2;
490     }
491
492   if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
493     {
494       if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
495         did_stdout = 1;
496       else
497         did_stdout = 2;
498     }
499
500   if (fstat (STDERR_FILENO, &statbuf)==-1 && errno==EBADF)
501     {
502       if (open ("/dev/null", O_WRONLY) == STDERR_FILENO)
503         did_stderr = 1;
504       else
505         did_stderr = 2;
506     }
507
508   /* It's hard to log this sort of thing since the filehandle we would
509      complain to may be closed... */
510   if (!did_stderr)
511     complain = stderr;
512   else if (!did_stdout)
513     complain = stdout;
514   else
515     complain = NULL;
516
517   if (complain)
518     {
519       if (did_stdin == 1)
520         fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname);
521       if (did_stdout == 1)
522         fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname);
523       if (did_stderr == 1)
524         fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname);
525
526       if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
527         fprintf(complain,"%s: fatal: unable to reopen standard input,"
528                 " output, or error\n", pgmname);
529     }
530
531   if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
532     exit (3);
533 #else /* !(HAVE_STAT && !HAVE_W32_SYSTEM) */
534   (void)pgmname;
535 #endif
536 }
537
538
539 /* Hack required for Windows.  */
540 void
541 gnupg_allow_set_foregound_window (pid_t pid)
542 {
543   if (!pid)
544     log_info ("%s called with invalid pid %lu\n",
545               "gnupg_allow_set_foregound_window", (unsigned long)pid);
546 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
547   else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid))
548     log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
549                (unsigned long)pid, w32_strerror (-1));
550 #endif
551 }
552
553 int
554 gnupg_remove (const char *fname)
555 {
556 #ifdef HAVE_W32CE_SYSTEM
557   int rc;
558   wchar_t *wfname;
559
560   wfname = utf8_to_wchar (fname);
561   if (!wfname)
562     rc = 0;
563   else
564     {
565       rc = DeleteFile (wfname);
566       xfree (wfname);
567     }
568   if (!rc)
569     return -1; /* ERRNO is automagically provided by gpg-error.h.  */
570   return 0;
571 #else
572   return remove (fname);
573 #endif
574 }
575
576
577 #ifndef HAVE_W32_SYSTEM
578 static mode_t
579 modestr_to_mode (const char *modestr)
580 {
581   mode_t mode = 0;
582
583   if (modestr && *modestr)
584     {
585       modestr++;
586       if (*modestr && *modestr++ == 'r')
587         mode |= S_IRUSR;
588       if (*modestr && *modestr++ == 'w')
589         mode |= S_IWUSR;
590       if (*modestr && *modestr++ == 'x')
591         mode |= S_IXUSR;
592       if (*modestr && *modestr++ == 'r')
593         mode |= S_IRGRP;
594       if (*modestr && *modestr++ == 'w')
595         mode |= S_IWGRP;
596       if (*modestr && *modestr++ == 'x')
597         mode |= S_IXGRP;
598       if (*modestr && *modestr++ == 'r')
599         mode |= S_IROTH;
600       if (*modestr && *modestr++ == 'w')
601         mode |= S_IWOTH;
602       if (*modestr && *modestr++ == 'x')
603         mode |= S_IXOTH;
604     }
605
606   return mode;
607 }
608 #endif
609
610
611 /* A wrapper around mkdir which takes a string for the mode argument.
612    This makes it easier to handle the mode argument which is not
613    defined on all systems.  The format of the modestring is
614
615       "-rwxrwxrwx"
616
617    '-' is a don't care or not set.  'r', 'w', 'x' are read allowed,
618    write allowed, execution allowed with the first group for the user,
619    the second for the group and the third for all others.  If the
620    string is shorter than above the missing mode characters are meant
621    to be not set.  */
622 int
623 gnupg_mkdir (const char *name, const char *modestr)
624 {
625 #ifdef HAVE_W32CE_SYSTEM
626   wchar_t *wname;
627   (void)modestr;
628
629   wname = utf8_to_wchar (name);
630   if (!wname)
631     return -1;
632   if (!CreateDirectoryW (wname, NULL))
633     {
634       xfree (wname);
635       return -1;  /* ERRNO is automagically provided by gpg-error.h.  */
636     }
637   xfree (wname);
638   return 0;
639 #elif MKDIR_TAKES_ONE_ARG
640   (void)modestr;
641   /* Note: In the case of W32 we better use CreateDirectory and try to
642      set appropriate permissions.  However using mkdir is easier
643      because this sets ERRNO.  */
644   return mkdir (name);
645 #else
646   return mkdir (name, modestr_to_mode (modestr));
647 #endif
648 }
649
650
651 /* A wrapper around chmod which takes a string for the mode argument.
652    This makes it easier to handle the mode argument which is not
653    defined on all systems.  The format of the modestring is the same
654    as for gnupg_mkdir.  */
655 int
656 gnupg_chmod (const char *name, const char *modestr)
657 {
658 #ifdef HAVE_W32_SYSTEM
659   (void)name;
660   (void)modestr;
661   return 0;
662 #else
663   return chmod (name, modestr_to_mode (modestr));
664 #endif
665 }
666
667
668 /* Our version of mkdtemp.  The API is identical to POSIX.1-2008
669    version.  We do not use a system provided mkdtemp because we have a
670    good RNG instantly available and this way we don't have diverging
671    versions.  */
672 char *
673 gnupg_mkdtemp (char *tmpl)
674 {
675   /* A lower bound on the number of temporary files to attempt to
676      generate.  The maximum total number of temporary file names that
677      can exist for a given template is 62**6 (5*36**3 for Windows).
678      It should never be necessary to try all these combinations.
679      Instead if a reasonable number of names is tried (we define
680      reasonable as 62**3 or 5*36**3) fail to give the system
681      administrator the chance to remove the problems.  */
682 #ifdef HAVE_W32_SYSTEM
683   static const char letters[] =
684     "abcdefghijklmnopqrstuvwxyz0123456789";
685 # define NUMBER_OF_LETTERS 36
686 # define ATTEMPTS_MIN (5 * 36 * 36 * 36)
687 #else
688   static const char letters[] =
689     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
690 # define NUMBER_OF_LETTERS 62
691 # define ATTEMPTS_MIN (62 * 62 * 62)
692 #endif
693   int len;
694   char *XXXXXX;
695   uint64_t value;
696   unsigned int count;
697   int save_errno = errno;
698   /* The number of times to attempt to generate a temporary file.  To
699      conform to POSIX, this must be no smaller than TMP_MAX.  */
700 #if ATTEMPTS_MIN < TMP_MAX
701   unsigned int attempts = TMP_MAX;
702 #else
703   unsigned int attempts = ATTEMPTS_MIN;
704 #endif
705
706   len = strlen (tmpl);
707   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
708     {
709       gpg_err_set_errno (EINVAL);
710       return NULL;
711     }
712
713   /* This is where the Xs start.  */
714   XXXXXX = &tmpl[len - 6];
715
716   /* Get a random start value.  */
717   gcry_create_nonce (&value, sizeof value);
718
719   /* Loop until a directory was created.  */
720   for (count = 0; count < attempts; value += 7777, ++count)
721     {
722       uint64_t v = value;
723
724       /* Fill in the random bits.  */
725       XXXXXX[0] = letters[v % NUMBER_OF_LETTERS];
726       v /= NUMBER_OF_LETTERS;
727       XXXXXX[1] = letters[v % NUMBER_OF_LETTERS];
728       v /= NUMBER_OF_LETTERS;
729       XXXXXX[2] = letters[v % NUMBER_OF_LETTERS];
730       v /= NUMBER_OF_LETTERS;
731       XXXXXX[3] = letters[v % NUMBER_OF_LETTERS];
732       v /= NUMBER_OF_LETTERS;
733       XXXXXX[4] = letters[v % NUMBER_OF_LETTERS];
734       v /= NUMBER_OF_LETTERS;
735       XXXXXX[5] = letters[v % NUMBER_OF_LETTERS];
736
737       if (!gnupg_mkdir (tmpl, "-rwx"))
738         {
739           gpg_err_set_errno (save_errno);
740           return tmpl;
741         }
742       if (errno != EEXIST)
743         return NULL;
744     }
745
746   /* We got out of the loop because we ran out of combinations to try.  */
747   gpg_err_set_errno (EEXIST);
748   return NULL;
749 }
750
751
752 int
753 gnupg_setenv (const char *name, const char *value, int overwrite)
754 {
755 #ifdef HAVE_W32CE_SYSTEM
756   (void)name;
757   (void)value;
758   (void)overwrite;
759   return 0;
760 #else /*!W32CE*/
761 # ifdef HAVE_W32_SYSTEM
762   /*  Windows maintains (at least) two sets of environment variables.
763       One set can be accessed by GetEnvironmentVariable and
764       SetEnvironmentVariable.  This set is inherited by the children.
765       The other set is maintained in the C runtime, and is accessed
766       using getenv and putenv.  We try to keep them in sync by
767       modifying both sets.  */
768   {
769     int exists;
770     char tmpbuf[10];
771     exists = GetEnvironmentVariable (name, tmpbuf, sizeof tmpbuf);
772
773     if ((! exists || overwrite) && !SetEnvironmentVariable (name, value))
774       {
775         gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
776         return -1;
777       }
778   }
779 # endif /*W32*/
780
781 # ifdef HAVE_SETENV
782   return setenv (name, value, overwrite);
783 # else /*!HAVE_SETENV*/
784   if (! getenv (name) || overwrite)
785     {
786       char *buf;
787
788       (void)overwrite;
789       if (!name || !value)
790         {
791           gpg_err_set_errno (EINVAL);
792           return -1;
793         }
794       buf = strconcat (name, "=", value, NULL);
795       if (!buf)
796         return -1;
797 # if __GNUC__
798 #  warning no setenv - using putenv but leaking memory.
799 # endif
800       return putenv (buf);
801     }
802   return 0;
803 # endif /*!HAVE_SETENV*/
804 #endif /*!W32CE*/
805 }
806
807
808 int
809 gnupg_unsetenv (const char *name)
810 {
811 #ifdef HAVE_W32CE_SYSTEM
812   (void)name;
813   return 0;
814 #else /*!W32CE*/
815 # ifdef HAVE_W32_SYSTEM
816   /*  Windows maintains (at least) two sets of environment variables.
817       One set can be accessed by GetEnvironmentVariable and
818       SetEnvironmentVariable.  This set is inherited by the children.
819       The other set is maintained in the C runtime, and is accessed
820       using getenv and putenv.  We try to keep them in sync by
821       modifying both sets.  */
822   if (!SetEnvironmentVariable (name, NULL))
823     {
824       gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
825       return -1;
826     }
827 # endif /*W32*/
828
829 # ifdef HAVE_UNSETENV
830   return unsetenv (name);
831 # else /*!HAVE_UNSETENV*/
832   {
833     char *buf;
834
835     if (!name)
836       {
837         gpg_err_set_errno (EINVAL);
838         return -1;
839       }
840     buf = xtrystrdup (name);
841     if (!buf)
842       return -1;
843 #  if __GNUC__
844 #   warning no unsetenv - trying putenv but leaking memory.
845 #  endif
846     return putenv (buf);
847   }
848 # endif /*!HAVE_UNSETENV*/
849 #endif /*!W32CE*/
850 }
851
852
853 /* Return the current working directory as a malloced string.  Return
854    NULL and sets ERRNo on error.  */
855 char *
856 gnupg_getcwd (void)
857 {
858   char *buffer;
859   size_t size = 100;
860
861   for (;;)
862     {
863       buffer = xtrymalloc (size+1);
864       if (!buffer)
865         return NULL;
866 #ifdef HAVE_W32CE_SYSTEM
867       strcpy (buffer, "/");  /* Always "/".  */
868       return buffer;
869 #else
870       if (getcwd (buffer, size) == buffer)
871         return buffer;
872       xfree (buffer);
873       if (errno != ERANGE)
874         return NULL;
875       size *= 2;
876 #endif
877     }
878 }
879
880
881 \f
882 #ifdef HAVE_W32CE_SYSTEM
883 /* There is a isatty function declaration in cegcc but it does not
884    make sense, thus we redefine it.  */
885 int
886 _gnupg_isatty (int fd)
887 {
888   (void)fd;
889   return 0;
890 }
891 #endif
892
893
894 #ifdef HAVE_W32CE_SYSTEM
895 /* Replacement for getenv which takes care of the our use of getenv.
896    The code is not thread safe but we expect it to work in all cases
897    because it is called for the first time early enough.  */
898 char *
899 _gnupg_getenv (const char *name)
900 {
901   static int initialized;
902   static char *assuan_debug;
903
904   if (!initialized)
905     {
906       assuan_debug = read_w32_registry_string (NULL,
907                                                "\\Software\\GNU\\libassuan",
908                                                "debug");
909       initialized = 1;
910     }
911
912   if (!strcmp (name, "ASSUAN_DEBUG"))
913     return assuan_debug;
914   else
915     return NULL;
916 }
917
918 #endif /*HAVE_W32CE_SYSTEM*/
919
920
921 #ifdef HAVE_W32_SYSTEM
922 /* Return the user's security identifier from the current process.  */
923 PSID
924 w32_get_user_sid (void)
925 {
926   int okay = 0;
927   HANDLE proc = NULL;
928   HANDLE token = NULL;
929   TOKEN_USER *user = NULL;
930   PSID sid = NULL;
931   DWORD tokenlen, sidlen;
932
933   proc = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
934   if (!proc)
935     goto leave;
936
937   if (!OpenProcessToken (proc, TOKEN_QUERY, &token))
938     goto leave;
939
940   if (!GetTokenInformation (token, TokenUser, NULL, 0, &tokenlen)
941       && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
942     goto leave;
943
944   user = xtrymalloc (tokenlen);
945   if (!user)
946     goto leave;
947
948   if (!GetTokenInformation (token, TokenUser, user, tokenlen, &tokenlen))
949     goto leave;
950   if (!IsValidSid (user->User.Sid))
951     goto leave;
952   sidlen = GetLengthSid (user->User.Sid);
953   sid = xtrymalloc (sidlen);
954   if (!sid)
955     goto leave;
956   if (!CopySid (sidlen, sid, user->User.Sid))
957     goto leave;
958   okay = 1;
959
960  leave:
961   xfree (user);
962   if (token)
963     CloseHandle (token);
964   if (proc)
965     CloseHandle (proc);
966
967   if (!okay)
968     {
969       xfree (sid);
970       sid = NULL;
971     }
972   return sid;
973 }
974 #endif /*HAVE_W32_SYSTEM*/
975
976
977 \f
978 /* Support for inotify under Linux.  */
979
980 /* Store a new inotify file handle for SOCKET_NAME at R_FD or return
981  * an error code. */
982 gpg_error_t
983 gnupg_inotify_watch_socket (int *r_fd, const char *socket_name)
984 {
985 #if HAVE_INOTIFY_INIT
986   gpg_error_t err;
987   char *fname;
988   int fd;
989   char *p;
990
991   *r_fd = -1;
992
993   if (!socket_name)
994     return my_error (GPG_ERR_INV_VALUE);
995
996   fname = xtrystrdup (socket_name);
997   if (!fname)
998     return my_error_from_syserror ();
999
1000   fd = inotify_init ();
1001   if (fd == -1)
1002     {
1003       err = my_error_from_syserror ();
1004       xfree (fname);
1005       return err;
1006     }
1007
1008   /* We need to watch the directory for the file because there won't
1009    * be an IN_DELETE_SELF for a socket file.  To handle a removal of
1010    * the directory we also watch the directory itself. */
1011   p = strrchr (fname, '/');
1012   if (p)
1013     *p = 0;
1014   if (inotify_add_watch (fd, fname,
1015                          (IN_DELETE|IN_DELETE_SELF|IN_EXCL_UNLINK)) == -1)
1016     {
1017       err = my_error_from_syserror ();
1018       close (fd);
1019       xfree (fname);
1020       return err;
1021     }
1022
1023   xfree (fname);
1024
1025   *r_fd = fd;
1026   return 0;
1027 #else /*!HAVE_INOTIFY_INIT*/
1028
1029   (void)socket_name;
1030   *r_fd = -1;
1031   return my_error (GPG_ERR_NOT_SUPPORTED);
1032
1033 #endif /*!HAVE_INOTIFY_INIT*/
1034 }
1035
1036
1037 /* Read an inotify event and return true if it matches NAME or if it
1038  * sees an IN_DELETE_SELF event for the directory of NAME.  */
1039 int
1040 gnupg_inotify_has_name (int fd, const char *name)
1041 {
1042 #if USE_NPTH && HAVE_INOTIFY_INIT
1043 #define BUFSIZE_FOR_INOTIFY (sizeof (struct inotify_event) + 255 + 1)
1044   union {
1045     struct inotify_event ev;
1046     char _buf[sizeof (struct inotify_event) + 255 + 1];
1047   } buf;
1048   struct inotify_event *evp;
1049   int n;
1050
1051   n = npth_read (fd, &buf, sizeof buf);
1052   /* log_debug ("notify read: n=%d\n", n); */
1053   evp = &buf.ev;
1054   while (n >= sizeof (struct inotify_event))
1055     {
1056       /* log_debug ("             mask=%x len=%u name=(%s)\n", */
1057       /*        evp->mask, (unsigned int)evp->len, evp->len? evp->name:""); */
1058       if ((evp->mask & IN_UNMOUNT))
1059         {
1060           /* log_debug ("             found (dir unmounted)\n"); */
1061           return 3; /* Directory was unmounted.  */
1062         }
1063       if ((evp->mask & IN_DELETE_SELF))
1064         {
1065           /* log_debug ("             found (dir removed)\n"); */
1066           return 2; /* Directory was removed.  */
1067         }
1068       if ((evp->mask & IN_DELETE))
1069         {
1070           if (evp->len >= strlen (name) && !strcmp (evp->name, name))
1071             {
1072               /* log_debug ("             found (file removed)\n"); */
1073               return 1; /* File was removed.  */
1074             }
1075         }
1076       n -= sizeof (*evp) + evp->len;
1077       evp = (struct inotify_event *)(void *)
1078         ((char *)evp + sizeof (*evp) + evp->len);
1079     }
1080
1081 #else /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
1082
1083   (void)fd;
1084   (void)name;
1085
1086 #endif  /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
1087
1088   return 0; /* Not found.  */
1089 }
1090
1091
1092 /* Return a malloc'ed string that is the path to the passed
1093  * unix-domain socket (or return NULL if this is not a valid
1094  * unix-domain socket).  We use a plain int here because it is only
1095  * used on Linux.
1096  *
1097  * FIXME: This function needs to be moved to libassuan.  */
1098 #ifndef HAVE_W32_SYSTEM
1099 char *
1100 gnupg_get_socket_name (int fd)
1101 {
1102   struct sockaddr_un un;
1103   socklen_t len = sizeof(un);
1104   char *name = NULL;
1105
1106   if (getsockname (fd, (struct sockaddr*)&un, &len) != 0)
1107     log_error ("could not getsockname(%d): %s\n", fd,
1108                gpg_strerror (my_error_from_syserror ()));
1109   else if (un.sun_family != AF_UNIX)
1110     log_error ("file descriptor %d is not a unix-domain socket\n", fd);
1111   else if (len <= offsetof (struct sockaddr_un, sun_path))
1112     log_error ("socket name not present for file descriptor %d\n", fd);
1113   else if (len > sizeof(un))
1114     log_error ("socket name for file descriptor %d was truncated "
1115                "(passed %zu bytes, wanted %u)\n", fd, sizeof(un), len);
1116   else
1117     {
1118       size_t namelen = len - offsetof (struct sockaddr_un, sun_path);
1119
1120       /* log_debug ("file descriptor %d has path %s (%zu octets)\n", fd, */
1121       /*            un.sun_path, namelen); */
1122       name = xtrymalloc (namelen + 1);
1123       if (!name)
1124         log_error ("failed to allocate memory for name of fd %d: %s\n",
1125                    fd, gpg_strerror (my_error_from_syserror ()));
1126       else
1127         {
1128           memcpy (name, un.sun_path, namelen);
1129           name[namelen] = 0;
1130         }
1131     }
1132
1133   return name;
1134 }
1135 #endif /*!HAVE_W32_SYSTEM*/