Robustness fix.
[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 "util.h"
55 #include "i18n.h"
56
57 #include "sysutils.h"
58
59 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
60
61
62 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
63 #warning using trap_unaligned
64 static int
65 setsysinfo(unsigned long op, void *buffer, unsigned long size,
66                      int *start, void *arg, unsigned long flag)
67 {
68     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
69 }
70
71 void
72 trap_unaligned(void)
73 {
74     unsigned int buf[2];
75
76     buf[0] = SSIN_UACPROC;
77     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
78     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
79 }
80 #else
81 void
82 trap_unaligned(void)
83 {  /* dummy */
84 }
85 #endif
86
87
88 int
89 disable_core_dumps (void)
90 {
91 #ifdef HAVE_DOSISH_SYSTEM
92     return 0;
93 #else
94 # ifdef HAVE_SETRLIMIT
95     struct rlimit limit;
96
97     /* We only set the current limit unless we were not able to
98        retrieve the old value. */
99     if (getrlimit (RLIMIT_CORE, &limit))
100       limit.rlim_max = 0;
101     limit.rlim_cur = 0;
102     if( !setrlimit (RLIMIT_CORE, &limit) )
103         return 0;
104     if( errno != EINVAL && errno != ENOSYS )
105         log_fatal (_("can't disable core dumps: %s\n"), strerror(errno) );
106 #endif
107     return 1;
108 #endif
109 }
110
111 int
112 enable_core_dumps (void)
113 {
114 #ifdef HAVE_DOSISH_SYSTEM
115     return 0;
116 #else
117 # ifdef HAVE_SETRLIMIT
118     struct rlimit limit;
119
120     if (getrlimit (RLIMIT_CORE, &limit))
121       return 1;
122     limit.rlim_cur = limit.rlim_max;
123     setrlimit (RLIMIT_CORE, &limit);
124     return 1; /* We always return true because this function is
125                  merely a debugging aid. */
126 # endif
127     return 1;
128 #endif
129 }
130
131
132
133 /* Return a string which is used as a kind of process ID */
134 const byte *
135 get_session_marker( size_t *rlen )
136 {
137     static byte marker[SIZEOF_UNSIGNED_LONG*2];
138     static int initialized;
139
140     if ( !initialized ) {
141         volatile ulong aa, bb; /* we really want the uninitialized value */
142         ulong a, b;
143
144         initialized = 1;
145         /* Although this marker is guessable it is not easy to use
146          * for a faked control packet because an attacker does not
147          * have enough control about the time the verification does 
148          * take place.  Of course, we can add just more random but 
149          * than we need the random generator even for verification
150          * tasks - which does not make sense. */
151         a = aa ^ (ulong)getpid();
152         b = bb ^ (ulong)time(NULL);
153         memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
154         memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
155     }
156     *rlen = sizeof(marker);
157     return marker;
158 }
159
160
161 #if 0 /* not yet needed - Note that this will require inclusion of
162          cmacros.am in Makefile.am */
163 int
164 check_permissions(const char *path,int extension,int checkonly)
165 {
166 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
167   char *tmppath;
168   struct stat statbuf;
169   int ret=1;
170   int isdir=0;
171
172   if(opt.no_perm_warn)
173     return 0;
174
175   if(extension && path[0]!=DIRSEP_C)
176     {
177       if(strchr(path,DIRSEP_C))
178         tmppath=make_filename(path,NULL);
179       else
180         tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
181     }
182   else
183     tmppath=m_strdup(path);
184
185   /* It's okay if the file doesn't exist */
186   if(stat(tmppath,&statbuf)!=0)
187     {
188       ret=0;
189       goto end;
190     }
191
192   isdir=S_ISDIR(statbuf.st_mode);
193
194   /* Per-user files must be owned by the user.  Extensions must be
195      owned by the user or root. */
196   if((!extension && statbuf.st_uid != getuid()) ||
197      (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid()))
198     {
199       if(!checkonly)
200         log_info(_("Warning: unsafe ownership on %s \"%s\"\n"),
201                  isdir?"directory":extension?"extension":"file",path);
202       goto end;
203     }
204
205   /* This works for both directories and files - basically, we don't
206      care what the owner permissions are, so long as the group and
207      other permissions are 0 for per-user files, and non-writable for
208      extensions. */
209   if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) ||
210      (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0))
211     {
212       char *dir;
213
214       /* However, if the directory the directory/file is in is owned
215          by the user and is 700, then this is not a problem.
216          Theoretically, we could walk this test up to the root
217          directory /, but for the sake of sanity, I'm stopping at one
218          level down. */
219
220       dir= make_dirname (tmppath);
221       if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() &&
222          S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
223         {
224           xfree (dir);
225           ret=0;
226           goto end;
227         }
228
229       m_free(dir);
230
231       if(!checkonly)
232         log_info(_("Warning: unsafe permissions on %s \"%s\"\n"),
233                  isdir?"directory":extension?"extension":"file",path);
234       goto end;
235     }
236
237   ret=0;
238
239  end:
240   m_free(tmppath);
241
242   return ret;
243
244 #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
245
246   return 0;
247 }
248 #endif
249
250
251 /* Wrapper around the usual sleep fucntion.  This one won't wake up
252    before the sleep time has really elapsed.  When build with Pth it
253    merely calls pth_sleep and thus suspends only the current
254    thread. */
255 void
256 gnupg_sleep (unsigned int seconds)
257 {
258 #ifdef HAVE_PTH
259   /* With Pth we force a regular sleep for seconds == 0 so that also
260      the process will give up its timeslot.  */
261   if (!seconds)
262     {
263 # ifdef HAVE_W32_SYSTEM    
264       Sleep (0);
265 # else
266       sleep (0);
267 # endif
268     }
269   pth_sleep (seconds);
270 #else
271   /* Fixme:  make sure that a sleep won't wake up to early.  */
272 # ifdef HAVE_W32_SYSTEM    
273   Sleep (seconds*1000);
274 # else
275   sleep (seconds);
276 # endif
277 #endif
278 }
279
280
281 \f
282 /* Handle translation.  On W32, we provide handle values on the
283    command line directly and using special file names such as
284    "-&HANDLE".  However, in GPGME we can not directly inherit the
285    handles as this may interfere with other components in a
286    multithreaded application.  Thus, we inject the handles after
287    creating the GPG process.  The problem is that the handle numbers
288    change at injection, but it is too late to change the command line.
289    Hence this hack, which allows us to translate the handle values
290    in the command line to their new values after injection.
291
292    Handles that must be translated are those occuring in special file
293    names (see iobuf.c::check_special_filename) as well as those given
294    directly to options (see translate_sys2libc_fd_int).  */
295
296 /* For W32, we may have to translate handle values given on the
297    command line.  */
298 #define FD_TRANSLATE_MAX 8
299 static struct
300 {
301   int from;
302   int to;
303 } fd_translate[FD_TRANSLATE_MAX];
304
305 /* Number of entries used in fd_translate.  */
306 static int fd_translate_len;
307
308
309 /* Initialize the fd translation table.  This reads one line from
310    stdin which is expected to be in the format "FROM TO [...]" where
311    each "FROM TO" pair are two handle numbers.  Handle number FROM on
312    the command line is translated to handle number TO.  
313
314    Note that this function may be called while still being setuid.  */
315 void
316 translate_table_init (void)
317 {
318   /* Hold roughly 8 pairs of 64 bit numbers in hex notation:
319      "0xFEDCBA9876543210 0xFEDCBA9876543210".  8*19*2 - 1 = 303.  This
320      plans ahead for a time where a HANDLE is 64 bit.  */
321 #define TRANS_MAX 350
322   char line[TRANS_MAX + 1];
323   char *linep;
324   int idx;
325   int res;
326   int newl = 0;
327
328   /* We always read one line from stdin.  */
329   for (idx = 0; idx < TRANS_MAX; idx++)
330     {
331       do
332         res = read (0, &line[idx], 1);
333       while (res == -1 && errno == EINTR);
334       if (res != 1)
335         break;
336       if (line[idx] == '\n')
337         {
338           newl = 1;
339           break;
340         }
341     }
342   if (!newl)
343     {
344       char buf[1];
345       do
346         {
347           do
348             res = read (0, buf, 1);
349           while (res == -1 && errno == EINTR);
350         }
351       while (res == 1 && *buf != '\n');
352     }
353
354   line[idx] = '\0';
355   linep = line;
356
357   /* Now start to read mapping pairs.  */
358   for (idx = 0; idx < FD_TRANSLATE_MAX; idx++)
359     {
360       unsigned long from;
361       unsigned long to;
362       char *tail;
363
364       while (spacep (linep))
365         linep++;
366       if (*linep == '\0')
367         break;
368       from = strtoul (linep, &tail, 0);
369       if (tail == NULL || ! (*tail == '\0' || spacep (tail)))
370         break;
371       linep = tail;
372
373       while (spacep (linep))
374         linep++;
375       if (*linep == '\0')
376         break;
377       to = strtoul (linep, &tail, 0);
378       if (tail == NULL || ! (*tail == '\0' || spacep (tail)))
379         break;
380       linep = tail;
381
382       fd_translate[idx].from = from;
383       fd_translate[idx].to = to;
384       fd_translate_len++;
385     }
386 }
387
388
389 /* Translate a handle number.  */
390 int
391 translate_table_lookup (int fd)
392 {
393   int idx;
394
395   for (idx = 0; idx < fd_translate_len; idx++)
396     if (fd_translate[idx].from == fd)
397       return fd_translate[idx].to;
398   return fd;
399 }
400
401 \f
402 /* This function is a NOP for POSIX systems but required under Windows
403    as the file handles as returned by OS calls (like CreateFile) are
404    different from the libc file descriptors (like open). This function
405    translates system file handles to libc file handles.  FOR_WRITE
406    gives the direction of the handle.  */
407 int
408 translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
409 {
410 #ifdef HAVE_W32_SYSTEM
411   int x;
412
413   if (fd == GNUPG_INVALID_FD)
414     return -1;
415   
416   /* Note that _open_osfhandle is currently defined to take and return
417      a long.  */
418   x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
419   if (x == -1)
420     log_error ("failed to translate osfhandle %p\n", (void *) fd);
421   return x;
422 #else /*!HAVE_W32_SYSTEM */
423   return fd;
424 #endif
425 }
426
427
428 /* This is the same as translate_sys2libc_fd but takes an integer
429    which is assumed to be such an system handle.  */
430 int
431 translate_sys2libc_fd_int (int fd, int for_write)
432 {
433 #ifdef HAVE_W32_SYSTEM
434   if (fd <= 2)
435     return fd;  /* Do not do this for error, stdin, stdout, stderr. */
436
437   /* Note: If this function is ever used in a different context than
438      option parsing in the main function, a variant that does not do
439      translation probable needs to be used.  */
440   fd = translate_table_lookup (fd);
441
442   return translate_sys2libc_fd ((void*)fd, for_write);
443 #else
444   fd = translate_table_lookup (fd);
445   return fd;
446 #endif
447 }
448
449
450
451 /* Replacement for tmpfile().  This is required because the tmpfile
452    function of Windows' runtime library is broken, insecure, ignores
453    TMPDIR and so on.  In addition we create a file with an inheritable
454    handle.  */
455 FILE *
456 gnupg_tmpfile (void)
457 {
458 #ifdef HAVE_W32_SYSTEM
459   int attempts, n;
460   char buffer[MAX_PATH+7+12+1];
461   char *name, *p;
462   HANDLE file;
463   int pid = GetCurrentProcessId ();
464   unsigned int value;
465   int i;
466   SECURITY_ATTRIBUTES sec_attr;
467
468   memset (&sec_attr, 0, sizeof sec_attr );
469   sec_attr.nLength = sizeof sec_attr;
470   sec_attr.bInheritHandle = TRUE;
471
472   n = GetTempPath (MAX_PATH+1, buffer);
473   if (!n || n > MAX_PATH || strlen (buffer) > MAX_PATH)
474     {
475       errno = ENOENT;
476       return NULL;
477     }
478   p = buffer + strlen (buffer);
479   p = stpcpy (p, "_gnupg");
480   /* We try to create the directory but don't care about an error as
481      it may already exist and the CreateFile would throw an error
482      anyway.  */
483   CreateDirectory (buffer, NULL);
484   *p++ = '\\';
485   name = p;
486   for (attempts=0; attempts < 10; attempts++)
487     {
488       p = name;
489       value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
490       for (i=0; i < 8; i++)
491         {
492           *p++ = tohex (((value >> 28) & 0x0f));
493           value <<= 4;
494         }
495       strcpy (p, ".tmp");
496       file = CreateFile (buffer,
497                          GENERIC_READ | GENERIC_WRITE,
498                          0,
499                          &sec_attr,
500                          CREATE_NEW,
501                          FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
502                          NULL);
503       if (file != INVALID_HANDLE_VALUE)
504         {
505           FILE *fp;
506           int fd = _open_osfhandle ((long)file, 0);
507           if (fd == -1)
508             {
509               CloseHandle (file);
510               return NULL;
511             }
512           fp = fdopen (fd, "w+b");
513           if (!fp)
514             {
515               int save = errno;
516               close (fd);
517               errno = save;
518               return NULL;
519             }
520           return fp;
521         }
522       Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
523     }
524   errno = ENOENT;
525   return NULL;
526 #else /*!HAVE_W32_SYSTEM*/
527   return tmpfile ();
528 #endif /*!HAVE_W32_SYSTEM*/
529 }
530
531
532 /* Make sure that the standard file descriptors are opened. Obviously
533    some folks close them before an exec and the next file we open will
534    get one of them assigned and thus any output (i.e. diagnostics) end
535    up in that file (e.g. the trustdb).  Not actually a gpg problem as
536    this will hapen with almost all utilities when called in a wrong
537    way.  However we try to minimize the damage here and raise
538    awareness of the problem.
539
540    Must be called before we open any files! */
541 void
542 gnupg_reopen_std (const char *pgmname)
543 {  
544 #if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
545   struct stat statbuf;
546   int did_stdin = 0;
547   int did_stdout = 0;
548   int did_stderr = 0;
549   FILE *complain;
550
551   if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF)
552     {
553       if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
554         did_stdin = 1;
555       else
556         did_stdin = 2;
557     }
558   
559   if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
560     {
561       if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
562         did_stdout = 1;
563       else
564         did_stdout = 2;
565     }
566
567   if (fstat (STDERR_FILENO, &statbuf)==-1 && errno==EBADF)
568     {
569       if (open ("/dev/null", O_WRONLY) == STDERR_FILENO)
570         did_stderr = 1;
571       else
572         did_stderr = 2;
573     }
574
575   /* It's hard to log this sort of thing since the filehandle we would
576      complain to may be closed... */
577   if (!did_stderr)
578     complain = stderr;
579   else if (!did_stdout)
580     complain = stdout;
581   else
582     complain = NULL;
583
584   if (complain)
585     {
586       if (did_stdin == 1)
587         fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname);
588       if (did_stdout == 1)
589         fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname);
590       if (did_stderr == 1)
591         fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname);
592
593       if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
594         fprintf(complain,"%s: fatal: unable to reopen standard input,"
595                 " output, or error\n", pgmname);
596     }
597
598   if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
599     exit (3);
600 #endif /* HAVE_STAT && !HAVE_W32_SYSTEM */
601 }
602
603
604 /* Hack required for Windows.  */
605 void 
606 gnupg_allow_set_foregound_window (pid_t pid)
607 {
608   if (!pid || pid == (pid_t)(-1))
609     log_info ("%s called with invalid pid %lu\n",
610               "gnupg_allow_set_foregound_window", (unsigned long)pid);
611 #ifdef HAVE_W32_SYSTEM  
612   else if (!AllowSetForegroundWindow (pid))
613     log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
614                (unsigned long)pid, w32_strerror (-1));
615 #endif
616 }