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