Add code for explicit selection of pooled A records.
[gnupg.git] / common / sysutils.c
1 /* sysutils.c -  system helpers
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004,
3  *               2007, 2008  Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth.  */
24 # undef HAVE_PTH
25 # undef USE_GNU_PTH
26 #endif
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <errno.h>
33 #ifdef HAVE_STAT
34 # include <sys/stat.h>
35 #endif
36 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
37 # include <asm/sysinfo.h>
38 # include <asm/unistd.h>
39 #endif
40 #ifdef HAVE_SETRLIMIT
41 # include <time.h>
42 # include <sys/time.h>
43 # include <sys/resource.h>
44 #endif
45 #ifdef HAVE_W32_SYSTEM
46 # define WINVER 0x0500  /* Required for AllowSetForegroundWindow.  */
47 # include <windows.h>
48 #endif
49 #ifdef HAVE_PTH
50 # include <pth.h>
51 #endif
52 #include <fcntl.h>
53
54 #include <assuan.h>
55
56 #include "setenv.h"   /* Gnulib replacement.  */
57
58 #include "util.h"
59 #include "i18n.h"
60
61 #include "sysutils.h"
62
63 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
64
65
66 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
67 #warning using trap_unaligned
68 static int
69 setsysinfo(unsigned long op, void *buffer, unsigned long size,
70                      int *start, void *arg, unsigned long flag)
71 {
72     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
73 }
74
75 void
76 trap_unaligned(void)
77 {
78     unsigned int buf[2];
79
80     buf[0] = SSIN_UACPROC;
81     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
82     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
83 }
84 #else
85 void
86 trap_unaligned(void)
87 {  /* dummy */
88 }
89 #endif
90
91
92 int
93 disable_core_dumps (void)
94 {
95 #ifdef HAVE_DOSISH_SYSTEM
96     return 0;
97 #else
98 # ifdef HAVE_SETRLIMIT
99     struct rlimit limit;
100
101     /* We only set the current limit unless we were not able to
102        retrieve the old value. */
103     if (getrlimit (RLIMIT_CORE, &limit))
104       limit.rlim_max = 0;
105     limit.rlim_cur = 0;
106     if( !setrlimit (RLIMIT_CORE, &limit) )
107         return 0;
108     if( errno != EINVAL && errno != ENOSYS )
109         log_fatal (_("can't disable core dumps: %s\n"), strerror(errno) );
110 #endif
111     return 1;
112 #endif
113 }
114
115 int
116 enable_core_dumps (void)
117 {
118 #ifdef HAVE_DOSISH_SYSTEM
119     return 0;
120 #else
121 # ifdef HAVE_SETRLIMIT
122     struct rlimit limit;
123
124     if (getrlimit (RLIMIT_CORE, &limit))
125       return 1;
126     limit.rlim_cur = limit.rlim_max;
127     setrlimit (RLIMIT_CORE, &limit);
128     return 1; /* We always return true because this function is
129                  merely a debugging aid. */
130 # endif
131     return 1;
132 #endif
133 }
134
135
136
137 /* Return a string which is used as a kind of process ID.  */
138 const byte *
139 get_session_marker (size_t *rlen)
140 {
141   static byte marker[SIZEOF_UNSIGNED_LONG*2];
142   static int initialized;
143
144   if (!initialized)
145     {
146       gcry_create_nonce (marker, sizeof marker);
147       initialized = 1;
148     }
149   *rlen = sizeof (marker);
150   return marker;
151 }
152
153 /* Return a random number in an unsigned int. */
154 unsigned int
155 get_uint_nonce (void)
156 {
157   unsigned int value;
158
159   gcry_create_nonce (&value, sizeof value);
160   return value;
161 }
162
163
164
165 #if 0 /* not yet needed - Note that this will require inclusion of
166          cmacros.am in Makefile.am */
167 int
168 check_permissions(const char *path,int extension,int checkonly)
169 {
170 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
171   char *tmppath;
172   struct stat statbuf;
173   int ret=1;
174   int isdir=0;
175
176   if(opt.no_perm_warn)
177     return 0;
178
179   if(extension && path[0]!=DIRSEP_C)
180     {
181       if(strchr(path,DIRSEP_C))
182         tmppath=make_filename(path,NULL);
183       else
184         tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
185     }
186   else
187     tmppath=m_strdup(path);
188
189   /* It's okay if the file doesn't exist */
190   if(stat(tmppath,&statbuf)!=0)
191     {
192       ret=0;
193       goto end;
194     }
195
196   isdir=S_ISDIR(statbuf.st_mode);
197
198   /* Per-user files must be owned by the user.  Extensions must be
199      owned by the user or root. */
200   if((!extension && statbuf.st_uid != getuid()) ||
201      (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid()))
202     {
203       if(!checkonly)
204         log_info(_("Warning: unsafe ownership on %s \"%s\"\n"),
205                  isdir?"directory":extension?"extension":"file",path);
206       goto end;
207     }
208
209   /* This works for both directories and files - basically, we don't
210      care what the owner permissions are, so long as the group and
211      other permissions are 0 for per-user files, and non-writable for
212      extensions. */
213   if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) ||
214      (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0))
215     {
216       char *dir;
217
218       /* However, if the directory the directory/file is in is owned
219          by the user and is 700, then this is not a problem.
220          Theoretically, we could walk this test up to the root
221          directory /, but for the sake of sanity, I'm stopping at one
222          level down. */
223
224       dir= make_dirname (tmppath);
225       if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() &&
226          S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
227         {
228           xfree (dir);
229           ret=0;
230           goto end;
231         }
232
233       m_free(dir);
234
235       if(!checkonly)
236         log_info(_("Warning: unsafe permissions on %s \"%s\"\n"),
237                  isdir?"directory":extension?"extension":"file",path);
238       goto end;
239     }
240
241   ret=0;
242
243  end:
244   m_free(tmppath);
245
246   return ret;
247
248 #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
249
250   return 0;
251 }
252 #endif
253
254
255 /* Wrapper around the usual sleep fucntion.  This one won't wake up
256    before the sleep time has really elapsed.  When build with Pth it
257    merely calls pth_sleep and thus suspends only the current
258    thread. */
259 void
260 gnupg_sleep (unsigned int seconds)
261 {
262 #ifdef HAVE_PTH
263   /* With Pth we force a regular sleep for seconds == 0 so that also
264      the process will give up its timeslot.  */
265   if (!seconds)
266     {
267 # ifdef HAVE_W32_SYSTEM
268       Sleep (0);
269 # else
270       sleep (0);
271 # endif
272     }
273   pth_sleep (seconds);
274 #else
275   /* Fixme:  make sure that a sleep won't wake up to early.  */
276 # ifdef HAVE_W32_SYSTEM
277   Sleep (seconds*1000);
278 # else
279   sleep (seconds);
280 # endif
281 #endif
282 }
283
284
285 /* This function is a NOP for POSIX systems but required under Windows
286    as the file handles as returned by OS calls (like CreateFile) are
287    different from the libc file descriptors (like open). This function
288    translates system file handles to libc file handles.  FOR_WRITE
289    gives the direction of the handle.  */
290 int
291 translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
292 {
293 #if defined(HAVE_W32CE_SYSTEM)
294   (void)for_write;
295   return (int) fd;
296 #elif defined(HAVE_W32_SYSTEM)
297   int x;
298
299   if (fd == GNUPG_INVALID_FD)
300     return -1;
301
302   /* Note that _open_osfhandle is currently defined to take and return
303      a long.  */
304   x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
305   if (x == -1)
306     log_error ("failed to translate osfhandle %p\n", (void *) fd);
307   return x;
308 #else /*!HAVE_W32_SYSTEM */
309   (void)for_write;
310   return fd;
311 #endif
312 }
313
314 /* This is the same as translate_sys2libc_fd but takes an integer
315    which is assumed to be such an system handle.  On WindowsCE the
316    passed FD is a rendezvous ID and the function finishes the pipe
317    creation. */
318 int
319 translate_sys2libc_fd_int (int fd, int for_write)
320 {
321 #if HAVE_W32CE_SYSTEM
322   fd = (int) _assuan_w32ce_finish_pipe (fd, for_write);
323   return translate_sys2libc_fd ((void*)fd, for_write);
324 #elif HAVE_W32_SYSTEM
325   if (fd <= 2)
326     return fd;  /* Do not do this for error, stdin, stdout, stderr. */
327
328   return translate_sys2libc_fd ((void*)fd, for_write);
329 #else
330   (void)for_write;
331   return fd;
332 #endif
333 }
334
335
336
337 /* Replacement for tmpfile().  This is required because the tmpfile
338    function of Windows' runtime library is broken, insecure, ignores
339    TMPDIR and so on.  In addition we create a file with an inheritable
340    handle.  */
341 FILE *
342 gnupg_tmpfile (void)
343 {
344 #ifdef HAVE_W32_SYSTEM
345   int attempts, n;
346 #ifdef HAVE_W32CE_SYSTEM
347   wchar_t buffer[MAX_PATH+7+12+1];
348 # define mystrlen(a) wcslen (a)
349   wchar_t *name, *p;
350 #else
351   char buffer[MAX_PATH+7+12+1];
352 # define mystrlen(a) strlen (a)
353   char *name, *p;
354 #endif
355   HANDLE file;
356   int pid = GetCurrentProcessId ();
357   unsigned int value;
358   int i;
359   SECURITY_ATTRIBUTES sec_attr;
360
361   memset (&sec_attr, 0, sizeof sec_attr );
362   sec_attr.nLength = sizeof sec_attr;
363   sec_attr.bInheritHandle = TRUE;
364
365   n = GetTempPath (MAX_PATH+1, buffer);
366   if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH)
367     {
368       gpg_err_set_errno (ENOENT);
369       return NULL;
370     }
371   p = buffer + mystrlen (buffer);
372 #ifdef HAVE_W32CE_SYSTEM
373   wcscpy (p, L"_gnupg");
374   p += 7;
375 #else
376   p = stpcpy (p, "_gnupg");
377 #endif
378   /* We try to create the directory but don't care about an error as
379      it may already exist and the CreateFile would throw an error
380      anyway.  */
381   CreateDirectory (buffer, NULL);
382   *p++ = '\\';
383   name = p;
384   for (attempts=0; attempts < 10; attempts++)
385     {
386       p = name;
387       value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
388       for (i=0; i < 8; i++)
389         {
390           *p++ = tohex (((value >> 28) & 0x0f));
391           value <<= 4;
392         }
393 #ifdef HAVE_W32CE_SYSTEM
394       wcscpy (p, L".tmp");
395 #else
396       strcpy (p, ".tmp");
397 #endif
398       file = CreateFile (buffer,
399                          GENERIC_READ | GENERIC_WRITE,
400                          0,
401                          &sec_attr,
402                          CREATE_NEW,
403                          FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
404                          NULL);
405       if (file != INVALID_HANDLE_VALUE)
406         {
407           FILE *fp;
408 #ifdef HAVE_W32CE_SYSTEM
409           int fd = (int)file;
410           fp = _wfdopen (fd, L"w+b");
411 #else
412           int fd = _open_osfhandle ((long)file, 0);
413           if (fd == -1)
414             {
415               CloseHandle (file);
416               return NULL;
417             }
418           fp = fdopen (fd, "w+b");
419 #endif
420           if (!fp)
421             {
422               int save = errno;
423               close (fd);
424               gpg_err_set_errno (save);
425               return NULL;
426             }
427           return fp;
428         }
429       Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
430     }
431   gpg_err_set_errno (ENOENT);
432   return NULL;
433 #undef mystrlen
434 #else /*!HAVE_W32_SYSTEM*/
435   return tmpfile ();
436 #endif /*!HAVE_W32_SYSTEM*/
437 }
438
439
440 /* Make sure that the standard file descriptors are opened. Obviously
441    some folks close them before an exec and the next file we open will
442    get one of them assigned and thus any output (i.e. diagnostics) end
443    up in that file (e.g. the trustdb).  Not actually a gpg problem as
444    this will hapen with almost all utilities when called in a wrong
445    way.  However we try to minimize the damage here and raise
446    awareness of the problem.
447
448    Must be called before we open any files! */
449 void
450 gnupg_reopen_std (const char *pgmname)
451 {
452 #if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
453   struct stat statbuf;
454   int did_stdin = 0;
455   int did_stdout = 0;
456   int did_stderr = 0;
457   FILE *complain;
458
459   if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF)
460     {
461       if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
462         did_stdin = 1;
463       else
464         did_stdin = 2;
465     }
466
467   if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
468     {
469       if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
470         did_stdout = 1;
471       else
472         did_stdout = 2;
473     }
474
475   if (fstat (STDERR_FILENO, &statbuf)==-1 && errno==EBADF)
476     {
477       if (open ("/dev/null", O_WRONLY) == STDERR_FILENO)
478         did_stderr = 1;
479       else
480         did_stderr = 2;
481     }
482
483   /* It's hard to log this sort of thing since the filehandle we would
484      complain to may be closed... */
485   if (!did_stderr)
486     complain = stderr;
487   else if (!did_stdout)
488     complain = stdout;
489   else
490     complain = NULL;
491
492   if (complain)
493     {
494       if (did_stdin == 1)
495         fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname);
496       if (did_stdout == 1)
497         fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname);
498       if (did_stderr == 1)
499         fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname);
500
501       if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
502         fprintf(complain,"%s: fatal: unable to reopen standard input,"
503                 " output, or error\n", pgmname);
504     }
505
506   if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
507     exit (3);
508 #else /* !(HAVE_STAT && !HAVE_W32_SYSTEM) */
509   (void)pgmname;
510 #endif
511 }
512
513
514 /* Hack required for Windows.  */
515 void
516 gnupg_allow_set_foregound_window (pid_t pid)
517 {
518   if (!pid)
519     log_info ("%s called with invalid pid %lu\n",
520               "gnupg_allow_set_foregound_window", (unsigned long)pid);
521 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
522   else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid))
523     log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
524                (unsigned long)pid, w32_strerror (-1));
525 #endif
526 }
527
528 int
529 gnupg_remove (const char *fname)
530 {
531 #ifdef HAVE_W32CE_SYSTEM
532   int rc;
533   wchar_t *wfname;
534
535   wfname = utf8_to_wchar (fname);
536   if (!wfname)
537     rc = 0;
538   else
539     {
540       rc = DeleteFile (wfname);
541       xfree (wfname);
542     }
543   if (!rc)
544     return -1; /* ERRNO is automagically provided by gpg-error.h.  */
545   return 0;
546 #else
547   return remove (fname);
548 #endif
549 }
550
551
552 /* A wrapper around mkdir which takes a string for the mode argument.
553    This makes it easier to handle the mode argument which is not
554    defined on all systems.  The format of the modestring is
555
556       "-rwxrwxrwx"
557
558    '-' is a don't care or not set.  'r', 'w', 'x' are read allowed,
559    write allowed, execution allowed with the first group for the user,
560    the second for the group and the third for all others.  If the
561    string is shorter than above the missing mode characters are meant
562    to be not set.  */
563 int
564 gnupg_mkdir (const char *name, const char *modestr)
565 {
566 #ifdef HAVE_W32CE_SYSTEM
567   wchar_t *wname;
568   (void)modestr;
569
570   wname = utf8_to_wchar (name);
571   if (!wname)
572     return -1;
573   if (!CreateDirectoryW (wname, NULL))
574     {
575       xfree (wname);
576       return -1;  /* ERRNO is automagically provided by gpg-error.h.  */
577     }
578   xfree (wname);
579   return 0;
580 #elif MKDIR_TAKES_ONE_ARG
581   (void)modestr;
582   /* Note: In the case of W32 we better use CreateDirectory and try to
583      set appropriate permissions.  However using mkdir is easier
584      because this sets ERRNO.  */
585   return mkdir (name);
586 #else
587   mode_t mode = 0;
588
589   if (modestr && *modestr)
590     {
591       modestr++;
592       if (*modestr && *modestr++ == 'r')
593         mode |= S_IRUSR;
594       if (*modestr && *modestr++ == 'w')
595         mode |= S_IWUSR;
596       if (*modestr && *modestr++ == 'x')
597         mode |= S_IXUSR;
598       if (*modestr && *modestr++ == 'r')
599         mode |= S_IRGRP;
600       if (*modestr && *modestr++ == 'w')
601         mode |= S_IWGRP;
602       if (*modestr && *modestr++ == 'x')
603         mode |= S_IXGRP;
604       if (*modestr && *modestr++ == 'r')
605         mode |= S_IROTH;
606       if (*modestr && *modestr++ == 'w')
607         mode |= S_IWOTH;
608       if (*modestr && *modestr++ == 'x')
609         mode |= S_IXOTH;
610     }
611   return mkdir (name, mode);
612 #endif
613 }
614
615
616 int
617 gnupg_setenv (const char *name, const char *value, int overwrite)
618 {
619 #ifdef HAVE_W32CE_SYSTEM
620   (void)name;
621   (void)value;
622   (void)overwrite;
623   return 0;
624 #else
625   return setenv (name, value, overwrite);
626 #endif
627 }
628
629 int
630 gnupg_unsetenv (const char *name)
631 {
632 #ifdef HAVE_W32CE_SYSTEM
633   (void)name;
634   return 0;
635 #else
636 # ifdef HAVE_UNSETENV
637   return unsetenv (name);
638 # else
639   return putenv (name);
640 # endif
641 #endif
642 }
643
644 #ifdef HAVE_W32CE_SYSTEM
645 /* There is a isatty function declaration in cegcc but it does not
646    make sense, thus we redefine it.  */
647 int
648 _gnupg_isatty (int fd)
649 {
650   (void)fd;
651   return 0;
652 }
653 #endif
654
655
656 #ifdef HAVE_W32CE_SYSTEM
657 /* Replacement for getenv which takes care of the our use of getenv.
658    The code is not thread safe but we expect it to work in all cases
659    because it is called for the first time early enough.  */
660 char *
661 _gnupg_getenv (const char *name)
662 {
663   static int initialized;
664   static char *assuan_debug;
665
666   if (!initialized)
667     {
668       assuan_debug = read_w32_registry_string (NULL,
669                                                "\\Software\\GNU\\libassuan",
670                                                "debug");
671       initialized = 1;
672     }
673
674   if (!strcmp (name, "ASSUAN_DEBUG"))
675     return assuan_debug;
676   else
677     return NULL;
678 }
679
680 #endif /*HAVE_W32CE_SYSTEM*/