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 <limits.h>
44 #include <sys/types.h>
45 #include <unistd.h>
46 #include <errno.h>
47 #ifdef HAVE_STAT
48 # include <sys/stat.h>
49 #endif
50 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
51 # include <asm/sysinfo.h>
52 # include <asm/unistd.h>
53 #endif
54 #include <time.h>
55 #ifdef HAVE_SETRLIMIT
56 # include <sys/time.h>
57 # include <sys/resource.h>
58 #endif
59 #ifdef HAVE_PWD_H
60 # include <pwd.h>
61 # include <grp.h>
62 #endif /*HAVE_PWD_H*/
63 #ifdef HAVE_W32_SYSTEM
64 # if WINVER < 0x0500
65 #   define WINVER 0x0500  /* Required for AllowSetForegroundWindow.  */
66 # endif
67 # ifdef HAVE_WINSOCK2_H
68 #  include <winsock2.h>
69 # endif
70 # include <windows.h>
71 #else /*!HAVE_W32_SYSTEM*/
72 # include <sys/socket.h>
73 # include <sys/un.h>
74 #endif
75 #ifdef HAVE_INOTIFY_INIT
76 # include <sys/inotify.h>
77 #endif /*HAVE_INOTIFY_INIT*/
78 #ifdef HAVE_NPTH
79 # include <npth.h>
80 #endif
81 #include <fcntl.h>
82 #include <dirent.h>
83 
84 #include <assuan.h>
85 
86 #include "util.h"
87 #include "i18n.h"
88 
89 #include "sysutils.h"
90 
91 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
92 
93 
94 /* The object used with our opendir functions.  We need to define our
95  * own so that we can properly handle Unicode on Windows.  */
96 struct gnupg_dir_s
97 {
98 #ifdef HAVE_W32_SYSTEM
99   _WDIR *dir;                    /* The system's DIR pointer.  */
100 #else
101   DIR *dir;                      /* The system's DIR pointer.  */
102 #endif
103   struct gnupg_dirent_s dirent;  /* The current dirent.  */
104   size_t namesize;  /* If not 0 the allocated size of dirent.d_name.  */
105   char name[256];   /* Only used if NAMESIZE is 0.  */
106 };
107 
108 
109 /* Flag to tell whether special file names are enabled.  See gpg.c for
110  * an explanation of these file names.  */
111 static int allow_special_filenames;
112 
113 #ifdef HAVE_W32_SYSTEM
114 /* State of gnupg_inhibit_set_foregound_window.  */
115 static int inhibit_set_foregound_window;
116 #endif
117 
118 
119 static GPGRT_INLINE gpg_error_t
my_error_from_syserror(void)120 my_error_from_syserror (void)
121 {
122   return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
123 }
124 
125 static GPGRT_INLINE gpg_error_t
my_error(int e)126 my_error (int e)
127 {
128   return gpg_err_make (default_errsource, (e));
129 }
130 
131 
132 
133 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
134 #warning using trap_unaligned
135 static int
setsysinfo(unsigned long op,void * buffer,unsigned long size,int * start,void * arg,unsigned long flag)136 setsysinfo(unsigned long op, void *buffer, unsigned long size,
137 		     int *start, void *arg, unsigned long flag)
138 {
139     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
140 }
141 
142 void
trap_unaligned(void)143 trap_unaligned(void)
144 {
145     unsigned int buf[2];
146 
147     buf[0] = SSIN_UACPROC;
148     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
149     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
150 }
151 #else
152 void
trap_unaligned(void)153 trap_unaligned(void)
154 {  /* dummy */
155 }
156 #endif
157 
158 
159 int
disable_core_dumps(void)160 disable_core_dumps (void)
161 {
162 #ifdef HAVE_DOSISH_SYSTEM
163     return 0;
164 #else
165 # ifdef HAVE_SETRLIMIT
166     struct rlimit limit;
167 
168     /* We only set the current limit unless we were not able to
169        retrieve the old value. */
170     if (getrlimit (RLIMIT_CORE, &limit))
171       limit.rlim_max = 0;
172     limit.rlim_cur = 0;
173     if( !setrlimit (RLIMIT_CORE, &limit) )
174 	return 0;
175     if( errno != EINVAL && errno != ENOSYS )
176 	log_fatal (_("can't disable core dumps: %s\n"), strerror(errno) );
177 #endif
178     return 1;
179 #endif
180 }
181 
182 int
enable_core_dumps(void)183 enable_core_dumps (void)
184 {
185 #ifdef HAVE_DOSISH_SYSTEM
186     return 0;
187 #else
188 # ifdef HAVE_SETRLIMIT
189     struct rlimit limit;
190 
191     if (getrlimit (RLIMIT_CORE, &limit))
192       return 1;
193     limit.rlim_cur = limit.rlim_max;
194     setrlimit (RLIMIT_CORE, &limit);
195     return 1; /* We always return true because this function is
196                  merely a debugging aid. */
197 # endif
198     return 1;
199 #endif
200 }
201 
202 #ifdef HAVE_W32_SYSTEM
203 static int
any8bitchar(const char * string)204 any8bitchar (const char *string)
205 {
206   if (string)
207     for ( ; *string; string++)
208       if ((*string & 0x80))
209         return 1;
210   return 0;
211 }
212 #endif /*HAVE_W32_SYSTEM*/
213 
214 
215 /* Helper for gnupg_w32_set_errno.  */
216 #ifdef HAVE_W32_SYSTEM
217 static int
map_w32_to_errno(DWORD w32_err)218 map_w32_to_errno (DWORD w32_err)
219 {
220   switch (w32_err)
221     {
222     case 0:
223       return 0;
224 
225     case ERROR_FILE_NOT_FOUND:
226       return ENOENT;
227 
228     case ERROR_PATH_NOT_FOUND:
229       return ENOENT;
230 
231     case ERROR_ACCESS_DENIED:
232       return EPERM;  /* ReactOS uses EACCES ("Permission denied") and
233                       * is likely right because they used an
234                       * undocumented function to associate the error
235                       * codes.  However we have always used EPERM
236                       * ("Operation not permitted", e.g. function is
237                       * required to be called by root) and we better
238                       * stick to that to avoid surprising bugs. */
239 
240     case ERROR_INVALID_HANDLE:
241       return EBADF;
242 
243     case ERROR_INVALID_BLOCK:
244       return ENOMEM;
245 
246     case ERROR_NOT_ENOUGH_MEMORY:
247       return ENOMEM;
248 
249     case ERROR_NO_DATA:
250       return EPIPE;
251 
252     case ERROR_ALREADY_EXISTS:
253       return EEXIST;
254 
255       /* This mapping has been taken from reactOS.  */
256     case ERROR_TOO_MANY_OPEN_FILES: return EMFILE;
257     case ERROR_ARENA_TRASHED: return ENOMEM;
258     case ERROR_BAD_ENVIRONMENT: return E2BIG;
259     case ERROR_BAD_FORMAT: return ENOEXEC;
260     case ERROR_INVALID_DRIVE: return ENOENT;
261     case ERROR_CURRENT_DIRECTORY: return EACCES;
262     case ERROR_NOT_SAME_DEVICE: return EXDEV;
263     case ERROR_NO_MORE_FILES: return ENOENT;
264     case ERROR_WRITE_PROTECT: return EACCES;
265     case ERROR_BAD_UNIT: return EACCES;
266     case ERROR_NOT_READY: return EACCES;
267     case ERROR_BAD_COMMAND: return EACCES;
268     case ERROR_CRC: return EACCES;
269     case ERROR_BAD_LENGTH: return EACCES;
270     case ERROR_SEEK: return EACCES;
271     case ERROR_NOT_DOS_DISK: return EACCES;
272     case ERROR_SECTOR_NOT_FOUND: return EACCES;
273     case ERROR_OUT_OF_PAPER: return EACCES;
274     case ERROR_WRITE_FAULT: return EACCES;
275     case ERROR_READ_FAULT: return EACCES;
276     case ERROR_GEN_FAILURE: return EACCES;
277     case ERROR_SHARING_VIOLATION: return EACCES;
278     case ERROR_LOCK_VIOLATION: return EACCES;
279     case ERROR_WRONG_DISK: return EACCES;
280     case ERROR_SHARING_BUFFER_EXCEEDED: return EACCES;
281     case ERROR_BAD_NETPATH: return ENOENT;
282     case ERROR_NETWORK_ACCESS_DENIED: return EACCES;
283     case ERROR_BAD_NET_NAME: return ENOENT;
284     case ERROR_FILE_EXISTS: return EEXIST;
285     case ERROR_CANNOT_MAKE: return EACCES;
286     case ERROR_FAIL_I24: return EACCES;
287     case ERROR_NO_PROC_SLOTS: return EAGAIN;
288     case ERROR_DRIVE_LOCKED: return EACCES;
289     case ERROR_BROKEN_PIPE: return EPIPE;
290     case ERROR_DISK_FULL: return ENOSPC;
291     case ERROR_INVALID_TARGET_HANDLE: return EBADF;
292     case ERROR_WAIT_NO_CHILDREN: return ECHILD;
293     case ERROR_CHILD_NOT_COMPLETE: return ECHILD;
294     case ERROR_DIRECT_ACCESS_HANDLE: return EBADF;
295     case ERROR_SEEK_ON_DEVICE: return EACCES;
296     case ERROR_DIR_NOT_EMPTY: return ENOTEMPTY;
297     case ERROR_NOT_LOCKED: return EACCES;
298     case ERROR_BAD_PATHNAME: return ENOENT;
299     case ERROR_MAX_THRDS_REACHED: return EAGAIN;
300     case ERROR_LOCK_FAILED: return EACCES;
301     case ERROR_INVALID_STARTING_CODESEG: return ENOEXEC;
302     case ERROR_INVALID_STACKSEG: return ENOEXEC;
303     case ERROR_INVALID_MODULETYPE: return ENOEXEC;
304     case ERROR_INVALID_EXE_SIGNATURE: return ENOEXEC;
305     case ERROR_EXE_MARKED_INVALID: return ENOEXEC;
306     case ERROR_BAD_EXE_FORMAT: return ENOEXEC;
307     case ERROR_ITERATED_DATA_EXCEEDS_64k: return ENOEXEC;
308     case ERROR_INVALID_MINALLOCSIZE: return ENOEXEC;
309     case ERROR_DYNLINK_FROM_INVALID_RING: return ENOEXEC;
310     case ERROR_IOPL_NOT_ENABLED: return ENOEXEC;
311     case ERROR_INVALID_SEGDPL: return ENOEXEC;
312     case ERROR_AUTODATASEG_EXCEEDS_64k: return ENOEXEC;
313     case ERROR_RING2SEG_MUST_BE_MOVABLE: return ENOEXEC;
314     case ERROR_RELOC_CHAIN_XEEDS_SEGLIM: return ENOEXEC;
315     case ERROR_INFLOOP_IN_RELOC_CHAIN: return ENOEXEC;
316     case ERROR_FILENAME_EXCED_RANGE: return ENOENT;
317     case ERROR_NESTING_NOT_ALLOWED: return EAGAIN;
318     case ERROR_NOT_ENOUGH_QUOTA: return ENOMEM;
319 
320     default:
321       return EIO;
322     }
323 }
324 #endif /*HAVE_W32_SYSTEM*/
325 
326 
327 /* Set ERRNO from the Windows error.  EC may be -1 to use the last error.  */
328 #ifdef HAVE_W32_SYSTEM
329 void
gnupg_w32_set_errno(int ec)330 gnupg_w32_set_errno (int ec)
331 {
332   /* FIXME: Replace by gpgrt_w32_set_errno.  */
333   if (ec == -1)
334     ec = GetLastError ();
335   _set_errno (map_w32_to_errno (ec));
336 }
337 #endif /*HAVE_W32_SYSTEM*/
338 
339 
340 
341 /* Allow the use of special "-&nnn" style file names.  */
342 void
enable_special_filenames(void)343 enable_special_filenames (void)
344 {
345   allow_special_filenames = 1;
346 }
347 
348 
349 /* Return a string which is used as a kind of process ID.  */
350 const byte *
get_session_marker(size_t * rlen)351 get_session_marker (size_t *rlen)
352 {
353   static byte marker[SIZEOF_UNSIGNED_LONG*2];
354   static int initialized;
355 
356   if (!initialized)
357     {
358       gcry_create_nonce (marker, sizeof marker);
359       initialized = 1;
360     }
361   *rlen = sizeof (marker);
362   return marker;
363 }
364 
365 /* Return a random number in an unsigned int. */
366 unsigned int
get_uint_nonce(void)367 get_uint_nonce (void)
368 {
369   unsigned int value;
370 
371   gcry_create_nonce (&value, sizeof value);
372   return value;
373 }
374 
375 
376 
377 #if 0 /* not yet needed - Note that this will require inclusion of
378          cmacros.am in Makefile.am */
379 int
380 check_permissions(const char *path,int extension,int checkonly)
381 {
382 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
383   char *tmppath;
384   struct stat statbuf;
385   int ret=1;
386   int isdir=0;
387 
388   if(opt.no_perm_warn)
389     return 0;
390 
391   if(extension && path[0]!=DIRSEP_C)
392     {
393       if(strchr(path,DIRSEP_C))
394 	tmppath=make_filename(path,NULL);
395       else
396 	tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
397     }
398   else
399     tmppath=m_strdup(path);
400 
401   /* It's okay if the file doesn't exist */
402   if(stat(tmppath,&statbuf)!=0)
403     {
404       ret=0;
405       goto end;
406     }
407 
408   isdir=S_ISDIR(statbuf.st_mode);
409 
410   /* Per-user files must be owned by the user.  Extensions must be
411      owned by the user or root. */
412   if((!extension && statbuf.st_uid != getuid()) ||
413      (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid()))
414     {
415       if(!checkonly)
416 	log_info(_("Warning: unsafe ownership on %s \"%s\"\n"),
417 		 isdir?"directory":extension?"extension":"file",path);
418       goto end;
419     }
420 
421   /* This works for both directories and files - basically, we don't
422      care what the owner permissions are, so long as the group and
423      other permissions are 0 for per-user files, and non-writable for
424      extensions. */
425   if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) ||
426      (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0))
427     {
428       char *dir;
429 
430       /* However, if the directory the directory/file is in is owned
431          by the user and is 700, then this is not a problem.
432          Theoretically, we could walk this test up to the root
433          directory /, but for the sake of sanity, I'm stopping at one
434          level down. */
435 
436       dir= make_dirname (tmppath);
437       if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() &&
438 	 S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
439 	{
440 	  xfree (dir);
441 	  ret=0;
442 	  goto end;
443 	}
444 
445       m_free(dir);
446 
447       if(!checkonly)
448 	log_info(_("Warning: unsafe permissions on %s \"%s\"\n"),
449 		 isdir?"directory":extension?"extension":"file",path);
450       goto end;
451     }
452 
453   ret=0;
454 
455  end:
456   m_free(tmppath);
457 
458   return ret;
459 
460 #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
461 
462   return 0;
463 }
464 #endif
465 
466 
467 /* Wrapper around the usual sleep function.  This one won't wake up
468    before the sleep time has really elapsed.  When build with Pth it
469    merely calls pth_sleep and thus suspends only the current
470    thread. */
471 void
gnupg_sleep(unsigned int seconds)472 gnupg_sleep (unsigned int seconds)
473 {
474 #ifdef USE_NPTH
475   npth_sleep (seconds);
476 #else
477   /* Fixme:  make sure that a sleep won't wake up to early.  */
478 # ifdef HAVE_W32_SYSTEM
479   Sleep (seconds*1000);
480 # else
481   sleep (seconds);
482 # endif
483 #endif
484 }
485 
486 
487 /* Wrapper around the platforms usleep function.  This one won't wake
488  * up before the sleep time has really elapsed.  When build with nPth
489  * it merely calls npth_usleep and thus suspends only the current
490  * thread. */
491 void
gnupg_usleep(unsigned int usecs)492 gnupg_usleep (unsigned int usecs)
493 {
494 #if defined(USE_NPTH)
495 
496   npth_usleep (usecs);
497 
498 #elif defined(HAVE_W32_SYSTEM)
499 
500   Sleep ((usecs + 999) / 1000);
501 
502 #elif defined(HAVE_NANOSLEEP)
503 
504   if (usecs)
505     {
506       struct timespec req;
507       struct timespec rem;
508 
509       req.tv_sec  = usecs / 1000000;
510       req.tv_nsec = (usecs % 1000000) * 1000;
511       while (nanosleep (&req, &rem) < 0 && errno == EINTR)
512           req = rem;
513     }
514 
515 #else /*Standard Unix*/
516 
517   if (usecs)
518     {
519       struct timeval tv;
520 
521       tv.tv_sec  = usecs / 1000000;
522       tv.tv_usec = usecs % 1000000;
523       select (0, NULL, NULL, NULL, &tv);
524     }
525 
526 #endif
527 }
528 
529 
530 /* This function is a NOP for POSIX systems but required under Windows
531    as the file handles as returned by OS calls (like CreateFile) are
532    different from the libc file descriptors (like open). This function
533    translates system file handles to libc file handles.  FOR_WRITE
534    gives the direction of the handle.  */
535 int
translate_sys2libc_fd(gnupg_fd_t fd,int for_write)536 translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
537 {
538 #if defined(HAVE_W32CE_SYSTEM)
539   (void)for_write;
540   return (int) fd;
541 #elif defined(HAVE_W32_SYSTEM)
542   int x;
543 
544   if (fd == GNUPG_INVALID_FD)
545     return -1;
546 
547   /* Note that _open_osfhandle is currently defined to take and return
548      a long.  */
549   x = _open_osfhandle ((intptr_t)fd, for_write ? 1 : 0);
550   if (x == -1)
551     log_error ("failed to translate osfhandle %p\n", (void *) fd);
552   return x;
553 #else /*!HAVE_W32_SYSTEM */
554   (void)for_write;
555   return fd;
556 #endif
557 }
558 
559 /* This is the same as translate_sys2libc_fd but takes an integer
560    which is assumed to be such an system handle.  On WindowsCE the
561    passed FD is a rendezvous ID and the function finishes the pipe
562    creation. */
563 int
translate_sys2libc_fd_int(int fd,int for_write)564 translate_sys2libc_fd_int (int fd, int for_write)
565 {
566 #if HAVE_W32CE_SYSTEM
567   fd = (int) _assuan_w32ce_finish_pipe (fd, for_write);
568   return translate_sys2libc_fd ((void*)fd, for_write);
569 #elif HAVE_W32_SYSTEM
570   if (fd <= 2)
571     return fd;	/* Do not do this for error, stdin, stdout, stderr. */
572 
573   return translate_sys2libc_fd ((void*)fd, for_write);
574 #else
575   (void)for_write;
576   return fd;
577 #endif
578 }
579 
580 
581 /* Check whether FNAME has the form "-&nnnn", where N is a non-zero
582  * number.  Returns this number or -1 if it is not the case.  If the
583  * caller wants to use the file descriptor for writing FOR_WRITE shall
584  * be set to 1.  If NOTRANSLATE is set the Windows specific mapping is
585  * not done. */
586 int
check_special_filename(const char * fname,int for_write,int notranslate)587 check_special_filename (const char *fname, int for_write, int notranslate)
588 {
589   if (allow_special_filenames
590       && fname && *fname == '-' && fname[1] == '&')
591     {
592       int i;
593 
594       fname += 2;
595       for (i=0; digitp (fname+i); i++ )
596         ;
597       if (!fname[i])
598         return notranslate? atoi (fname)
599           /**/            : translate_sys2libc_fd_int (atoi (fname), for_write);
600     }
601   return -1;
602 }
603 
604 
605 /* Replacement for tmpfile().  This is required because the tmpfile
606    function of Windows' runtime library is broken, insecure, ignores
607    TMPDIR and so on.  In addition we create a file with an inheritable
608    handle.  */
609 FILE *
gnupg_tmpfile(void)610 gnupg_tmpfile (void)
611 {
612 #ifdef HAVE_W32_SYSTEM
613   int attempts, n;
614 #ifdef HAVE_W32CE_SYSTEM
615   wchar_t buffer[MAX_PATH+7+12+1];
616 # define mystrlen(a) wcslen (a)
617   wchar_t *name, *p;
618 #else
619   char buffer[MAX_PATH+7+12+1];
620 # define mystrlen(a) strlen (a)
621   char *name, *p;
622 #endif
623   HANDLE file;
624   int pid = GetCurrentProcessId ();
625   unsigned int value;
626   int i;
627   SECURITY_ATTRIBUTES sec_attr;
628 
629   memset (&sec_attr, 0, sizeof sec_attr );
630   sec_attr.nLength = sizeof sec_attr;
631   sec_attr.bInheritHandle = TRUE;
632 
633   n = GetTempPath (MAX_PATH+1, buffer);
634   if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH)
635     {
636       gpg_err_set_errno (ENOENT);
637       return NULL;
638     }
639   p = buffer + mystrlen (buffer);
640 #ifdef HAVE_W32CE_SYSTEM
641   wcscpy (p, L"_gnupg");
642   p += 7;
643 #else
644   p = stpcpy (p, "_gnupg");
645 #endif
646   /* We try to create the directory but don't care about an error as
647      it may already exist and the CreateFile would throw an error
648      anyway.  */
649   CreateDirectory (buffer, NULL);
650   *p++ = '\\';
651   name = p;
652   for (attempts=0; attempts < 10; attempts++)
653     {
654       p = name;
655       value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
656       for (i=0; i < 8; i++)
657         {
658           *p++ = tohex (((value >> 28) & 0x0f));
659           value <<= 4;
660         }
661 #ifdef HAVE_W32CE_SYSTEM
662       wcscpy (p, L".tmp");
663 #else
664       strcpy (p, ".tmp");
665 #endif
666       file = CreateFile (buffer,
667                          GENERIC_READ | GENERIC_WRITE,
668                          0,
669                          &sec_attr,
670                          CREATE_NEW,
671                          FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
672                          NULL);
673       if (file != INVALID_HANDLE_VALUE)
674         {
675           FILE *fp;
676 #ifdef HAVE_W32CE_SYSTEM
677           int fd = (int)file;
678           fp = _wfdopen (fd, L"w+b");
679 #else
680           int fd = _open_osfhandle ((intptr_t)file, 0);
681           if (fd == -1)
682             {
683               CloseHandle (file);
684               return NULL;
685             }
686           fp = fdopen (fd, "w+b");
687 #endif
688           if (!fp)
689             {
690               int save = errno;
691               close (fd);
692               gpg_err_set_errno (save);
693               return NULL;
694             }
695           return fp;
696         }
697       Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
698     }
699   gpg_err_set_errno (ENOENT);
700   return NULL;
701 #undef mystrlen
702 #else /*!HAVE_W32_SYSTEM*/
703   return tmpfile ();
704 #endif /*!HAVE_W32_SYSTEM*/
705 }
706 
707 
708 /* Make sure that the standard file descriptors are opened. Obviously
709    some folks close them before an exec and the next file we open will
710    get one of them assigned and thus any output (i.e. diagnostics) end
711    up in that file (e.g. the trustdb).  Not actually a gpg problem as
712    this will happen with almost all utilities when called in a wrong
713    way.  However we try to minimize the damage here and raise
714    awareness of the problem.
715 
716    Must be called before we open any files! */
717 void
gnupg_reopen_std(const char * pgmname)718 gnupg_reopen_std (const char *pgmname)
719 {
720 #ifdef F_GETFD
721   int did_stdin = 0;
722   int did_stdout = 0;
723   int did_stderr = 0;
724   FILE *complain;
725 
726   if (fcntl (STDIN_FILENO, F_GETFD) == -1 && errno ==EBADF)
727     {
728       if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
729 	did_stdin = 1;
730       else
731 	did_stdin = 2;
732     }
733 
734   if (fcntl (STDOUT_FILENO, F_GETFD) == -1 && errno == EBADF)
735     {
736       if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
737 	did_stdout = 1;
738       else
739 	did_stdout = 2;
740     }
741 
742   if (fcntl (STDERR_FILENO, F_GETFD)==-1 && errno==EBADF)
743     {
744       if (open ("/dev/null", O_WRONLY) == STDERR_FILENO)
745 	did_stderr = 1;
746       else
747 	did_stderr = 2;
748     }
749 
750   /* It's hard to log this sort of thing since the filehandle we would
751      complain to may be closed... */
752   if (!did_stderr)
753     complain = stderr;
754   else if (!did_stdout)
755     complain = stdout;
756   else
757     complain = NULL;
758 
759   if (complain)
760     {
761       if (did_stdin == 1)
762 	fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname);
763       if (did_stdout == 1)
764 	fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname);
765       if (did_stderr == 1)
766 	fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname);
767 
768       if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
769 	fprintf(complain,"%s: fatal: unable to reopen standard input,"
770 		" output, or error\n", pgmname);
771     }
772 
773   if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
774     exit (3);
775 #else /* !F_GETFD */
776   (void)pgmname;
777 #endif
778 }
779 
780 
781 /* Inhibit calls to AllowSetForegroundWindow on Windows.  Calling this
782  * with YES set to true calls to gnupg_allow_set_foregound_window are
783  * shunted.  */
784 void
gnupg_inhibit_set_foregound_window(int yes)785 gnupg_inhibit_set_foregound_window (int yes)
786 {
787 #ifdef HAVE_W32_SYSTEM
788   inhibit_set_foregound_window = yes;
789 #else
790   (void)yes;
791 #endif
792 }
793 
794 
795 /* Hack required for Windows.  */
796 void
gnupg_allow_set_foregound_window(pid_t pid)797 gnupg_allow_set_foregound_window (pid_t pid)
798 {
799   if (!pid)
800     log_info ("%s called with invalid pid %lu\n",
801               "gnupg_allow_set_foregound_window", (unsigned long)pid);
802 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
803   else if (inhibit_set_foregound_window)
804     ;
805   else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid))
806     log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
807                (unsigned long)pid, w32_strerror (-1));
808 #endif
809 }
810 
811 int
gnupg_remove(const char * fname)812 gnupg_remove (const char *fname)
813 {
814 #ifdef HAVE_W32_SYSTEM
815   int rc;
816   wchar_t *wfname;
817 
818   wfname = utf8_to_wchar (fname);
819   if (!wfname)
820     rc = 0;
821   else
822     {
823       rc = DeleteFileW (wfname);
824       if (!rc)
825         gnupg_w32_set_errno (-1);
826       xfree (wfname);
827     }
828   if (!rc)
829     return -1;
830   return 0;
831 #else
832   return remove (fname);
833 #endif
834 }
835 
836 
837 /* Helper for gnupg_rename_file.  */
838 #ifdef HAVE_W32_SYSTEM
839 static int
w32_rename(const char * oldname,const char * newname)840 w32_rename (const char *oldname, const char *newname)
841 {
842   if (any8bitchar (oldname) || any8bitchar (newname))
843     {
844       wchar_t *woldname, *wnewname;
845       int ret;
846 
847       woldname = utf8_to_wchar (oldname);
848       if (!woldname)
849         return -1;
850       wnewname = utf8_to_wchar (newname);
851       if (!wnewname)
852         {
853           xfree (wnewname);
854           return -1;
855         }
856       ret = _wrename (woldname, wnewname);
857       xfree (wnewname);
858       xfree (woldname);
859       return ret;
860     }
861   else
862     return rename (oldname, newname);
863 }
864 #endif /*HAVE_W32_SYSTEM*/
865 
866 
867 /* Wrapper for rename(2) to handle Windows peculiarities.  If
868  * BLOCK_SIGNALS is not NULL and points to a variable set to true, all
869  * signals will be blocked by calling gnupg_block_all_signals; the
870  * caller needs to call gnupg_unblock_all_signals if that variable is
871  * still set to true on return. */
872 gpg_error_t
gnupg_rename_file(const char * oldname,const char * newname,int * block_signals)873 gnupg_rename_file (const char *oldname, const char *newname, int *block_signals)
874 {
875   gpg_error_t err = 0;
876 
877   if (block_signals && *block_signals)
878     gnupg_block_all_signals ();
879 
880 #ifdef HAVE_DOSISH_SYSTEM
881   {
882     int wtime = 0;
883 
884     gnupg_remove (newname);
885   again:
886     if (w32_rename (oldname, newname))
887       {
888         if (GetLastError () == ERROR_SHARING_VIOLATION)
889           {
890             /* Another process has the file open.  We do not use a
891              * lock for read but instead we wait until the other
892              * process has closed the file.  This may take long but
893              * that would also be the case with a dotlock approach for
894              * read and write.  Note that we don't need this on Unix
895              * due to the inode concept.
896              *
897              * So let's wait until the rename has worked.  The retry
898              * intervals are 50, 100, 200, 400, 800, 50ms, ...  */
899             if (!wtime || wtime >= 800)
900               wtime = 50;
901             else
902               wtime *= 2;
903 
904             if (wtime >= 800)
905               log_info (_("waiting for file '%s' to become accessible ...\n"),
906                         oldname);
907 
908             Sleep (wtime);
909             goto again;
910           }
911         err = my_error_from_syserror ();
912       }
913   }
914 #else /* Unix */
915   {
916 #ifdef __riscos__
917     gnupg_remove (newname);
918 #endif
919     if (rename (oldname, newname) )
920       err = my_error_from_syserror ();
921   }
922 #endif /* Unix */
923 
924   if (block_signals && *block_signals && err)
925     {
926       gnupg_unblock_all_signals ();
927       *block_signals = 0;
928     }
929 
930   if (err)
931     log_error (_("renaming '%s' to '%s' failed: %s\n"),
932                oldname, newname, gpg_strerror (err));
933   return err;
934 }
935 
936 
937 #ifndef HAVE_W32_SYSTEM
938 static mode_t
modestr_to_mode(const char * modestr,mode_t oldmode)939 modestr_to_mode (const char *modestr, mode_t oldmode)
940 {
941   static struct {
942     char letter;
943     mode_t value;
944   } table[] = { { '-', 0 },
945                 { 'r', S_IRUSR }, { 'w', S_IWUSR }, { 'x', S_IXUSR },
946                 { 'r', S_IRGRP }, { 'w', S_IWGRP }, { 'x', S_IXGRP },
947                 { 'r', S_IROTH }, { 'w', S_IWOTH }, { 'x', S_IXOTH } };
948   int idx;
949   mode_t mode = 0;
950 
951   /* For now we only support a string as used by ls(1) and no octal
952    * numbers.  The first character must be a dash.  */
953   for (idx=0; idx < 10 && *modestr; idx++, modestr++)
954     {
955       if (*modestr == table[idx].letter)
956         mode |= table[idx].value;
957       else if (*modestr == '.')
958         {
959           if (!idx)
960             ;  /* Skip the dummy.  */
961           else if ((oldmode & table[idx].value))
962             mode |= (oldmode & table[idx].value);
963           else
964             mode &= ~(oldmode & table[idx].value);
965         }
966       else if (*modestr != '-')
967         break;
968     }
969 
970 
971   return mode;
972 }
973 #endif
974 
975 
976 /* A wrapper around mkdir which takes a string for the mode argument.
977    This makes it easier to handle the mode argument which is not
978    defined on all systems.  The format of the modestring is
979 
980       "-rwxrwxrwx"
981 
982    '-' is a don't care or not set.  'r', 'w', 'x' are read allowed,
983    write allowed, execution allowed with the first group for the user,
984    the second for the group and the third for all others.  If the
985    string is shorter than above the missing mode characters are meant
986    to be not set.  */
987 int
gnupg_mkdir(const char * name,const char * modestr)988 gnupg_mkdir (const char *name, const char *modestr)
989 {
990   /* Note that gpgrt_mkdir also sets ERRNO in addition to returing an
991    * gpg-error style error code.  */
992   return gpgrt_mkdir (name, modestr);
993 }
994 
995 
996 /* A simple wrapper around chdir.  NAME is expected to be utf8
997  * encoded.  */
998 int
gnupg_chdir(const char * name)999 gnupg_chdir (const char *name)
1000 {
1001   /* Note that gpgrt_chdir also sets ERRNO in addition to returning an
1002    * gpg-error style error code.  */
1003   return gpgrt_chdir (name);
1004 }
1005 
1006 
1007 /* A wrapper around rmdir.  NAME is expected to be utf8 encoded.  */
1008 int
gnupg_rmdir(const char * name)1009 gnupg_rmdir (const char *name)
1010 {
1011 #ifdef HAVE_W32_SYSTEM
1012   int rc;
1013   wchar_t *wfname;
1014 
1015   wfname = utf8_to_wchar (name);
1016   if (!wfname)
1017     rc = 0;
1018   else
1019     {
1020       rc = RemoveDirectoryW (wfname);
1021       if (!rc)
1022         gnupg_w32_set_errno (-1);
1023       xfree (wfname);
1024     }
1025   if (!rc)
1026     return -1;
1027   return 0;
1028 #else
1029   return rmdir (name);
1030 #endif
1031 }
1032 
1033 
1034 /* A wrapper around chmod which takes a string for the mode argument.
1035    This makes it easier to handle the mode argument which is not
1036    defined on all systems.  The format of the modestring is the same
1037    as for gnupg_mkdir with extra feature that a '.' keeps the original
1038    mode bit.  */
1039 int
gnupg_chmod(const char * name,const char * modestr)1040 gnupg_chmod (const char *name, const char *modestr)
1041 {
1042 #ifdef HAVE_W32_SYSTEM
1043   (void)name;
1044   (void)modestr;
1045   return 0;
1046 #else
1047   mode_t oldmode;
1048   if (strchr (modestr, '.'))
1049     {
1050       /* Get the old mode so that a '.' can copy that bit.  */
1051       struct stat st;
1052 
1053       if (stat (name, &st))
1054         return -1;
1055       oldmode = st.st_mode;
1056     }
1057   else
1058     oldmode = 0;
1059   return chmod (name, modestr_to_mode (modestr, oldmode));
1060 #endif
1061 }
1062 
1063 
1064 /* Our version of mkdtemp.  The API is identical to POSIX.1-2008
1065    version.  We do not use a system provided mkdtemp because we have a
1066    good RNG instantly available and this way we don't have diverging
1067    versions.  */
1068 char *
gnupg_mkdtemp(char * tmpl)1069 gnupg_mkdtemp (char *tmpl)
1070 {
1071   /* A lower bound on the number of temporary files to attempt to
1072      generate.  The maximum total number of temporary file names that
1073      can exist for a given template is 62**6 (5*36**3 for Windows).
1074      It should never be necessary to try all these combinations.
1075      Instead if a reasonable number of names is tried (we define
1076      reasonable as 62**3 or 5*36**3) fail to give the system
1077      administrator the chance to remove the problems.  */
1078 #ifdef HAVE_W32_SYSTEM
1079   static const char letters[] =
1080     "abcdefghijklmnopqrstuvwxyz0123456789";
1081 # define NUMBER_OF_LETTERS 36
1082 # define ATTEMPTS_MIN (5 * 36 * 36 * 36)
1083 #else
1084   static const char letters[] =
1085     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
1086 # define NUMBER_OF_LETTERS 62
1087 # define ATTEMPTS_MIN (62 * 62 * 62)
1088 #endif
1089   int len;
1090   char *XXXXXX;
1091   uint64_t value;
1092   unsigned int count;
1093   int save_errno = errno;
1094   /* The number of times to attempt to generate a temporary file.  To
1095      conform to POSIX, this must be no smaller than TMP_MAX.  */
1096 #if ATTEMPTS_MIN < TMP_MAX
1097   unsigned int attempts = TMP_MAX;
1098 #else
1099   unsigned int attempts = ATTEMPTS_MIN;
1100 #endif
1101 
1102   len = strlen (tmpl);
1103   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
1104     {
1105       gpg_err_set_errno (EINVAL);
1106       return NULL;
1107     }
1108 
1109   /* This is where the Xs start.  */
1110   XXXXXX = &tmpl[len - 6];
1111 
1112   /* Get a random start value.  */
1113   gcry_create_nonce (&value, sizeof value);
1114 
1115   /* Loop until a directory was created.  */
1116   for (count = 0; count < attempts; value += 7777, ++count)
1117     {
1118       uint64_t v = value;
1119 
1120       /* Fill in the random bits.  */
1121       XXXXXX[0] = letters[v % NUMBER_OF_LETTERS];
1122       v /= NUMBER_OF_LETTERS;
1123       XXXXXX[1] = letters[v % NUMBER_OF_LETTERS];
1124       v /= NUMBER_OF_LETTERS;
1125       XXXXXX[2] = letters[v % NUMBER_OF_LETTERS];
1126       v /= NUMBER_OF_LETTERS;
1127       XXXXXX[3] = letters[v % NUMBER_OF_LETTERS];
1128       v /= NUMBER_OF_LETTERS;
1129       XXXXXX[4] = letters[v % NUMBER_OF_LETTERS];
1130       v /= NUMBER_OF_LETTERS;
1131       XXXXXX[5] = letters[v % NUMBER_OF_LETTERS];
1132 
1133       if (!gnupg_mkdir (tmpl, "-rwx"))
1134         {
1135           gpg_err_set_errno (save_errno);
1136           return tmpl;
1137         }
1138       if (errno != EEXIST)
1139 	return NULL;
1140     }
1141 
1142   /* We got out of the loop because we ran out of combinations to try.  */
1143   gpg_err_set_errno (EEXIST);
1144   return NULL;
1145 }
1146 
1147 
1148 int
gnupg_setenv(const char * name,const char * value,int overwrite)1149 gnupg_setenv (const char *name, const char *value, int overwrite)
1150 {
1151 #ifdef HAVE_W32CE_SYSTEM
1152   (void)name;
1153   (void)value;
1154   (void)overwrite;
1155   return 0;
1156 #else /*!W32CE*/
1157 # ifdef HAVE_W32_SYSTEM
1158   /*  Windows maintains (at least) two sets of environment variables.
1159       One set can be accessed by GetEnvironmentVariable and
1160       SetEnvironmentVariable.  This set is inherited by the children.
1161       The other set is maintained in the C runtime, and is accessed
1162       using getenv and putenv.  We try to keep them in sync by
1163       modifying both sets.  */
1164   {
1165     int exists;
1166     char tmpbuf[10];
1167     exists = GetEnvironmentVariable (name, tmpbuf, sizeof tmpbuf);
1168 
1169     if ((! exists || overwrite) && !SetEnvironmentVariable (name, value))
1170       {
1171         gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
1172         return -1;
1173       }
1174   }
1175 # endif /*W32*/
1176 
1177 # ifdef HAVE_SETENV
1178   return setenv (name, value, overwrite);
1179 # else /*!HAVE_SETENV*/
1180   if (! getenv (name) || overwrite)
1181     {
1182       char *buf;
1183 
1184       (void)overwrite;
1185       if (!name || !value)
1186         {
1187           gpg_err_set_errno (EINVAL);
1188           return -1;
1189         }
1190       buf = strconcat (name, "=", value, NULL);
1191       if (!buf)
1192         return -1;
1193 # if __GNUC__
1194 #  warning no setenv - using putenv but leaking memory.
1195 # endif
1196       return putenv (buf);
1197     }
1198   return 0;
1199 # endif /*!HAVE_SETENV*/
1200 #endif /*!W32CE*/
1201 }
1202 
1203 
1204 int
gnupg_unsetenv(const char * name)1205 gnupg_unsetenv (const char *name)
1206 {
1207 #ifdef HAVE_W32CE_SYSTEM
1208   (void)name;
1209   return 0;
1210 #else /*!W32CE*/
1211 # ifdef HAVE_W32_SYSTEM
1212   /*  Windows maintains (at least) two sets of environment variables.
1213       One set can be accessed by GetEnvironmentVariable and
1214       SetEnvironmentVariable.  This set is inherited by the children.
1215       The other set is maintained in the C runtime, and is accessed
1216       using getenv and putenv.  We try to keep them in sync by
1217       modifying both sets.  */
1218   if (!SetEnvironmentVariable (name, NULL))
1219     {
1220       gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
1221       return -1;
1222     }
1223 # endif /*W32*/
1224 
1225 # ifdef HAVE_UNSETENV
1226   return unsetenv (name);
1227 # else /*!HAVE_UNSETENV*/
1228   {
1229     char *buf;
1230 
1231     if (!name)
1232       {
1233         gpg_err_set_errno (EINVAL);
1234         return -1;
1235       }
1236     buf = xtrystrdup (name);
1237     if (!buf)
1238       return -1;
1239 #  if __GNUC__
1240 #   warning no unsetenv - trying putenv but leaking memory.
1241 #  endif
1242     return putenv (buf);
1243   }
1244 # endif /*!HAVE_UNSETENV*/
1245 #endif /*!W32CE*/
1246 }
1247 
1248 
1249 /* Return the current working directory as a malloced string.  Return
1250    NULL and sets ERRNO on error.  */
1251 char *
gnupg_getcwd(void)1252 gnupg_getcwd (void)
1253 {
1254   return gpgrt_getcwd ();
1255 }
1256 
1257 
1258 /* A simple wrapper around access.  NAME is expected to be utf8
1259  * encoded.  This function returns an error code and sets ERRNO. */
1260 gpg_err_code_t
gnupg_access(const char * name,int mode)1261 gnupg_access (const char *name, int mode)
1262 {
1263   return gpgrt_access (name, mode);
1264 }
1265 
1266 
1267 /* A wrapper around stat to handle Unicode file names under Windows.  */
1268 #ifdef HAVE_STAT
1269 int
gnupg_stat(const char * name,struct stat * statbuf)1270 gnupg_stat (const char *name, struct stat *statbuf)
1271 {
1272 # ifdef HAVE_W32_SYSTEM
1273   if (any8bitchar (name))
1274     {
1275       wchar_t *wname;
1276       struct _stat32 st32;
1277       int ret;
1278 
1279       wname = utf8_to_wchar (name);
1280       if (!wname)
1281         return -1;
1282       ret = _wstat (wname, &st32);
1283       xfree (wname);
1284       if (!ret)
1285         {
1286           statbuf->st_dev   = st32.st_dev;
1287           statbuf->st_ino   = st32.st_ino;
1288           statbuf->st_mode  = st32.st_mode;
1289           statbuf->st_nlink = st32.st_nlink;
1290           statbuf->st_uid   = st32.st_uid;
1291           statbuf->st_gid   = st32.st_gid;
1292           statbuf->st_rdev  = st32.st_rdev;
1293           statbuf->st_size  = st32.st_size;
1294           statbuf->st_atime = st32.st_atime;
1295           statbuf->st_mtime = st32.st_mtime;
1296           statbuf->st_ctime = st32.st_ctime;
1297         }
1298       return ret;
1299     }
1300   else
1301     return stat (name, statbuf);
1302 # else
1303   return stat (name, statbuf);
1304 # endif
1305 }
1306 #endif /*HAVE_STAT*/
1307 
1308 
1309 /* A wrapper around open to handle Unicode file names under Windows.  */
1310 int
gnupg_open(const char * name,int flags,unsigned int mode)1311 gnupg_open (const char *name, int flags, unsigned int mode)
1312 {
1313 #ifdef HAVE_W32_SYSTEM
1314   if (any8bitchar (name))
1315     {
1316       wchar_t *wname;
1317       int ret;
1318 
1319       wname = utf8_to_wchar (name);
1320       if (!wname)
1321         return -1;
1322       ret = _wopen (wname, flags, mode);
1323       xfree (wname);
1324       return ret;
1325     }
1326   else
1327     return open (name, flags, mode);
1328 #else
1329   return open (name, flags, mode);
1330 #endif
1331 }
1332 
1333 
1334 /* A wrapper around opendir to handle Unicode file names under
1335  * Windows.  This assumes the mingw toolchain.  */
1336 gnupg_dir_t
gnupg_opendir(const char * name)1337 gnupg_opendir (const char *name)
1338 {
1339 #ifdef HAVE_W32_SYSTEM
1340   _WDIR *dir;
1341   wchar_t *wname;
1342 #else
1343   DIR *dir;
1344 #endif
1345   gnupg_dir_t gdir;
1346 
1347 #ifdef HAVE_W32_SYSTEM
1348   /* Note: See gpgtar-create for an alternative implementation which
1349    * could be used here to avoid a mingw dependency.  */
1350   wname = utf8_to_wchar (name);
1351   if (!wname)
1352     return NULL;
1353   dir = _wopendir (wname);
1354   xfree (wname);
1355 #else
1356   dir = opendir (name);
1357 #endif
1358 
1359   if (!dir)
1360     return NULL;
1361 
1362   gdir = xtrymalloc (sizeof *gdir);
1363   if (!gdir)
1364     {
1365       int save_errno = errno;
1366 #ifdef HAVE_W32_SYSTEM
1367       _wclosedir (dir);
1368 #else
1369       closedir (dir);
1370 #endif
1371       gpg_err_set_errno (save_errno);
1372       return NULL;
1373     }
1374   gdir->dir = dir;
1375   gdir->namesize = 0;
1376   gdir->dirent.d_name = gdir->name;
1377 
1378   return gdir;
1379 }
1380 
1381 
1382 gnupg_dirent_t
gnupg_readdir(gnupg_dir_t gdir)1383 gnupg_readdir (gnupg_dir_t gdir)
1384 {
1385 #ifdef HAVE_W32_SYSTEM
1386   char *namebuffer = NULL;
1387   struct _wdirent *de;
1388 #else
1389   struct dirent *de;
1390 #endif
1391   size_t n;
1392   gnupg_dirent_t gde;
1393   const char *name;
1394 
1395   if (!gdir)
1396     {
1397       gpg_err_set_errno (EINVAL);
1398       return 0;
1399     }
1400 
1401 #ifdef HAVE_W32_SYSTEM
1402   de = _wreaddir (gdir->dir);
1403   if (!de)
1404     return NULL;
1405   namebuffer = wchar_to_utf8 (de->d_name);
1406   if (!namebuffer)
1407     return NULL;
1408   name = namebuffer;
1409 #else
1410   de = readdir (gdir->dir);
1411   if (!de)
1412     return NULL;
1413   name = de->d_name;
1414 #endif
1415 
1416   gde = &gdir->dirent;
1417   n = strlen (name);
1418   if (gdir->namesize)
1419     {
1420       /* Use allocated buffer.  */
1421       if (n+1 >= gdir->namesize || !gde->d_name)
1422         {
1423           gdir->namesize = n + 256;
1424           xfree (gde->d_name);
1425           gde->d_name = xtrymalloc (gdir->namesize);
1426           if (!gde->d_name)
1427             return NULL;  /* ERRNO is already set.  */
1428         }
1429       strcpy (gde->d_name, name);
1430     }
1431   else if (n+1 >= sizeof (gdir->name))
1432     {
1433       /* Switch to allocated buffer.  */
1434       gdir->namesize = n + 256;
1435       gde->d_name = xtrymalloc (gdir->namesize);
1436       if (!gde->d_name)
1437         return NULL;  /* ERRNO is already set.  */
1438       strcpy (gde->d_name, name);
1439     }
1440   else
1441     {
1442       /* Use static buffer.  */
1443       gde->d_name = gdir->name;
1444       strcpy (gde->d_name, name);
1445     }
1446 
1447 #ifdef HAVE_W32_SYSTEM
1448   xfree (namebuffer);
1449 #endif
1450 
1451   return gde;
1452 }
1453 
1454 
1455 int
gnupg_closedir(gnupg_dir_t gdir)1456 gnupg_closedir (gnupg_dir_t gdir)
1457 {
1458 #ifdef HAVE_W32_SYSTEM
1459   _WDIR *dir;
1460 #else
1461   DIR *dir;
1462 #endif
1463 
1464   if (!gdir)
1465     return 0;
1466   dir = gdir->dir;
1467   if (gdir->namesize)
1468     xfree (gdir->dirent.d_name);
1469   xfree (gdir);
1470 
1471 #ifdef HAVE_W32_SYSTEM
1472   return _wclosedir (dir);
1473 #else
1474   return closedir (dir);
1475 #endif
1476 }
1477 
1478 
1479 /* Try to set an envvar.  Print only a notice on error.  */
1480 #ifndef HAVE_W32_SYSTEM
1481 static void
try_set_envvar(const char * name,const char * value,int silent)1482 try_set_envvar (const char *name, const char *value, int silent)
1483 {
1484   if (gnupg_setenv (name, value, 1))
1485     if (!silent)
1486       log_info ("error setting envvar %s to '%s': %s\n", name, value,
1487                 gpg_strerror (my_error_from_syserror ()));
1488 }
1489 #endif /*!HAVE_W32_SYSTEM*/
1490 
1491 
1492 /* Switch to USER which is either a name or an UID.  This is a nop
1493  * under Windows.  Note that in general it is only possible to switch
1494  * to another user id if the process is running under root.  if silent
1495  * is set no diagnostics are printed.  */
1496 gpg_error_t
gnupg_chuid(const char * user,int silent)1497 gnupg_chuid (const char *user, int silent)
1498 {
1499 #ifdef HAVE_W32_SYSTEM
1500   (void)user;  /* Not implemented for Windows - ignore.  */
1501   (void)silent;
1502   return 0;
1503 
1504 #elif HAVE_PWD_H /* A proper Unix  */
1505   unsigned long ul;
1506   struct passwd *pw;
1507   struct stat st;
1508   char *endp;
1509   gpg_error_t err;
1510 
1511   gpg_err_set_errno (0);
1512   ul = strtoul (user, &endp, 10);
1513   if (errno || endp == user || *endp)
1514     pw = getpwnam (user);  /* Not a number; assume USER is a name.  */
1515   else
1516     pw = getpwuid ((uid_t)ul);
1517 
1518   if (!pw)
1519     {
1520       if (!silent)
1521         log_error ("user '%s' not found\n", user);
1522       return my_error (GPG_ERR_NOT_FOUND);
1523     }
1524 
1525   /* Try to set some envvars even if we are already that user.  */
1526   if (!stat (pw->pw_dir, &st))
1527     try_set_envvar ("HOME", pw->pw_dir, silent);
1528 
1529   try_set_envvar ("USER", pw->pw_name, silent);
1530   try_set_envvar ("LOGNAME", pw->pw_name, silent);
1531 #ifdef _AIX
1532   try_set_envvar ("LOGIN", pw->pw_name, silent);
1533 #endif
1534 
1535   if (getuid () == pw->pw_uid)
1536     return 0;  /* We are already this user.  */
1537 
1538   /* If we need to switch set PATH to a standard value and make sure
1539    * GNUPGHOME is not set. */
1540   try_set_envvar ("PATH", "/usr/local/bin:/usr/bin:/bin", silent);
1541   if (gnupg_unsetenv ("GNUPGHOME"))
1542     if (!silent)
1543       log_info ("error unsetting envvar %s: %s\n", "GNUPGHOME",
1544                 gpg_strerror (gpg_error_from_syserror ()));
1545 
1546   if (initgroups (pw->pw_name, pw->pw_gid))
1547     {
1548       err = my_error_from_syserror ();
1549       if (!silent)
1550         log_error ("error setting supplementary groups for '%s': %s\n",
1551                    pw->pw_name, gpg_strerror (err));
1552       return err;
1553     }
1554 
1555   if (setuid (pw->pw_uid))
1556     {
1557       err = my_error_from_syserror ();
1558       log_error ("error switching to user '%s': %s\n",
1559                  pw->pw_name, gpg_strerror (err));
1560       return err;
1561     }
1562 
1563   return 0;
1564 
1565 #else /*!HAVE_PWD_H */
1566   if (!silent)
1567     log_info ("system is missing passwd querying functions\n");
1568   return my_error (GPG_ERR_NOT_IMPLEMENTED);
1569 #endif
1570 }
1571 
1572 
1573 
1574 #ifdef HAVE_W32CE_SYSTEM
1575 /* There is a isatty function declaration in cegcc but it does not
1576    make sense, thus we redefine it.  */
1577 int
_gnupg_isatty(int fd)1578 _gnupg_isatty (int fd)
1579 {
1580   (void)fd;
1581   return 0;
1582 }
1583 #endif
1584 
1585 
1586 #ifdef HAVE_W32CE_SYSTEM
1587 /* Replacement for getenv which takes care of the our use of getenv.
1588    The code is not thread safe but we expect it to work in all cases
1589    because it is called for the first time early enough.  */
1590 char *
_gnupg_getenv(const char * name)1591 _gnupg_getenv (const char *name)
1592 {
1593   static int initialized;
1594   static char *assuan_debug;
1595 
1596   if (!initialized)
1597     {
1598       assuan_debug = read_w32_registry_string (NULL,
1599                                                "\\Software\\GNU\\libassuan",
1600                                                "debug");
1601       initialized = 1;
1602     }
1603 
1604   if (!strcmp (name, "ASSUAN_DEBUG"))
1605     return assuan_debug;
1606   else
1607     return NULL;
1608 }
1609 
1610 #endif /*HAVE_W32CE_SYSTEM*/
1611 
1612 
1613 #ifdef HAVE_W32_SYSTEM
1614 /* Return the user's security identifier from the current process.  */
1615 PSID
w32_get_user_sid(void)1616 w32_get_user_sid (void)
1617 {
1618   int okay = 0;
1619   HANDLE proc = NULL;
1620   HANDLE token = NULL;
1621   TOKEN_USER *user = NULL;
1622   PSID sid = NULL;
1623   DWORD tokenlen, sidlen;
1624 
1625   proc = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
1626   if (!proc)
1627     goto leave;
1628 
1629   if (!OpenProcessToken (proc, TOKEN_QUERY, &token))
1630     goto leave;
1631 
1632   if (!GetTokenInformation (token, TokenUser, NULL, 0, &tokenlen)
1633       && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1634     goto leave;
1635 
1636   user = xtrymalloc (tokenlen);
1637   if (!user)
1638     goto leave;
1639 
1640   if (!GetTokenInformation (token, TokenUser, user, tokenlen, &tokenlen))
1641     goto leave;
1642   if (!IsValidSid (user->User.Sid))
1643     goto leave;
1644   sidlen = GetLengthSid (user->User.Sid);
1645   sid = xtrymalloc (sidlen);
1646   if (!sid)
1647     goto leave;
1648   if (!CopySid (sidlen, sid, user->User.Sid))
1649     goto leave;
1650   okay = 1;
1651 
1652  leave:
1653   xfree (user);
1654   if (token)
1655     CloseHandle (token);
1656   if (proc)
1657     CloseHandle (proc);
1658 
1659   if (!okay)
1660     {
1661       xfree (sid);
1662       sid = NULL;
1663     }
1664   return sid;
1665 }
1666 #endif /*HAVE_W32_SYSTEM*/
1667 
1668 
1669 
1670 /* Support for inotify under Linux.  */
1671 
1672 /* Store a new inotify file handle for FNAME at R_FD or return an
1673  * error code.  This file descriptor watch the removal of FNAME. */
1674 gpg_error_t
gnupg_inotify_watch_delete_self(int * r_fd,const char * fname)1675 gnupg_inotify_watch_delete_self (int *r_fd, const char *fname)
1676 {
1677 #if HAVE_INOTIFY_INIT
1678   gpg_error_t err;
1679   int fd;
1680 
1681   *r_fd = -1;
1682 
1683   if (!fname)
1684     return my_error (GPG_ERR_INV_VALUE);
1685 
1686   fd = inotify_init ();
1687   if (fd == -1)
1688     return my_error_from_syserror ();
1689 
1690   if (inotify_add_watch (fd, fname, IN_DELETE_SELF) == -1)
1691     {
1692       err = my_error_from_syserror ();
1693       close (fd);
1694       return err;
1695     }
1696 
1697   *r_fd = fd;
1698   return 0;
1699 #else /*!HAVE_INOTIFY_INIT*/
1700 
1701   (void)fname;
1702   *r_fd = -1;
1703   return my_error (GPG_ERR_NOT_SUPPORTED);
1704 
1705 #endif /*!HAVE_INOTIFY_INIT*/
1706 }
1707 
1708 
1709 /* Store a new inotify file handle for SOCKET_NAME at R_FD or return
1710  * an error code. */
1711 gpg_error_t
gnupg_inotify_watch_socket(int * r_fd,const char * socket_name)1712 gnupg_inotify_watch_socket (int *r_fd, const char *socket_name)
1713 {
1714 #if HAVE_INOTIFY_INIT
1715   gpg_error_t err;
1716   char *fname;
1717   int fd;
1718   char *p;
1719 
1720   *r_fd = -1;
1721 
1722   if (!socket_name)
1723     return my_error (GPG_ERR_INV_VALUE);
1724 
1725   fname = xtrystrdup (socket_name);
1726   if (!fname)
1727     return my_error_from_syserror ();
1728 
1729   fd = inotify_init ();
1730   if (fd == -1)
1731     {
1732       err = my_error_from_syserror ();
1733       xfree (fname);
1734       return err;
1735     }
1736 
1737   /* We need to watch the directory for the file because there won't
1738    * be an IN_DELETE_SELF for a socket file.  To handle a removal of
1739    * the directory we also watch the directory itself. */
1740   p = strrchr (fname, '/');
1741   if (p)
1742     *p = 0;
1743   if (inotify_add_watch (fd, fname,
1744                          (IN_DELETE|IN_DELETE_SELF|IN_EXCL_UNLINK)) == -1)
1745     {
1746       err = my_error_from_syserror ();
1747       close (fd);
1748       xfree (fname);
1749       return err;
1750     }
1751 
1752   xfree (fname);
1753 
1754   *r_fd = fd;
1755   return 0;
1756 #else /*!HAVE_INOTIFY_INIT*/
1757 
1758   (void)socket_name;
1759   *r_fd = -1;
1760   return my_error (GPG_ERR_NOT_SUPPORTED);
1761 
1762 #endif /*!HAVE_INOTIFY_INIT*/
1763 }
1764 
1765 
1766 /* Read an inotify event and return true if it matches NAME or if it
1767  * sees an IN_DELETE_SELF event for the directory of NAME.  */
1768 int
gnupg_inotify_has_name(int fd,const char * name)1769 gnupg_inotify_has_name (int fd, const char *name)
1770 {
1771 #if USE_NPTH && HAVE_INOTIFY_INIT
1772 #define BUFSIZE_FOR_INOTIFY (sizeof (struct inotify_event) + 255 + 1)
1773   union {
1774     struct inotify_event ev;
1775     char _buf[sizeof (struct inotify_event) + 255 + 1];
1776   } buf;
1777   struct inotify_event *evp;
1778   int n;
1779 
1780   n = npth_read (fd, &buf, sizeof buf);
1781   /* log_debug ("notify read: n=%d\n", n); */
1782   evp = &buf.ev;
1783   while (n >= sizeof (struct inotify_event))
1784     {
1785       /* log_debug ("             mask=%x len=%u name=(%s)\n", */
1786       /*        evp->mask, (unsigned int)evp->len, evp->len? evp->name:""); */
1787       if ((evp->mask & IN_UNMOUNT))
1788         {
1789           /* log_debug ("             found (dir unmounted)\n"); */
1790           return 3; /* Directory was unmounted.  */
1791         }
1792       if ((evp->mask & IN_DELETE_SELF))
1793         {
1794           /* log_debug ("             found (dir removed)\n"); */
1795           return 2; /* Directory was removed.  */
1796         }
1797       if ((evp->mask & IN_DELETE))
1798         {
1799           if (evp->len >= strlen (name) && !strcmp (evp->name, name))
1800             {
1801               /* log_debug ("             found (file removed)\n"); */
1802               return 1; /* File was removed.  */
1803             }
1804         }
1805       n -= sizeof (*evp) + evp->len;
1806       evp = (struct inotify_event *)(void *)
1807         ((char *)evp + sizeof (*evp) + evp->len);
1808     }
1809 
1810 #else /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
1811 
1812   (void)fd;
1813   (void)name;
1814 
1815 #endif  /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
1816 
1817   return 0; /* Not found.  */
1818 }
1819 
1820 
1821 /* Return a malloc'ed string that is the path to the passed
1822  * unix-domain socket (or return NULL if this is not a valid
1823  * unix-domain socket).  We use a plain int here because it is only
1824  * used on Linux.
1825  *
1826  * FIXME: This function needs to be moved to libassuan.  */
1827 #ifndef HAVE_W32_SYSTEM
1828 char *
gnupg_get_socket_name(int fd)1829 gnupg_get_socket_name (int fd)
1830 {
1831   struct sockaddr_un un;
1832   socklen_t len = sizeof(un);
1833   char *name = NULL;
1834 
1835   if (getsockname (fd, (struct sockaddr*)&un, &len) != 0)
1836     log_error ("could not getsockname(%d): %s\n", fd,
1837                gpg_strerror (my_error_from_syserror ()));
1838   else if (un.sun_family != AF_UNIX)
1839     log_error ("file descriptor %d is not a unix-domain socket\n", fd);
1840   else if (len <= offsetof (struct sockaddr_un, sun_path))
1841     log_error ("socket name not present for file descriptor %d\n", fd);
1842   else if (len > sizeof(un))
1843     log_error ("socket name for file descriptor %d was truncated "
1844                "(passed %zu bytes, wanted %u)\n", fd, sizeof(un), len);
1845   else
1846     {
1847       size_t namelen = len - offsetof (struct sockaddr_un, sun_path);
1848 
1849       /* log_debug ("file descriptor %d has path %s (%zu octets)\n", fd, */
1850       /*            un.sun_path, namelen); */
1851       name = xtrymalloc (namelen + 1);
1852       if (!name)
1853         log_error ("failed to allocate memory for name of fd %d: %s\n",
1854                    fd, gpg_strerror (my_error_from_syserror ()));
1855       else
1856         {
1857           memcpy (name, un.sun_path, namelen);
1858           name[namelen] = 0;
1859         }
1860     }
1861 
1862   return name;
1863 }
1864 #endif /*!HAVE_W32_SYSTEM*/
1865 
1866 /* Check whether FD is valid.  */
1867 int
gnupg_fd_valid(int fd)1868 gnupg_fd_valid (int fd)
1869 {
1870   int d = dup (fd);
1871   if (d < 0)
1872     return 0;
1873   close (d);
1874   return 1;
1875 }
1876