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