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