Import/export of pkcs#12 now uses the gpg-agent directly.
[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 /* This function is a NOP for POSIX systems but required under Windows
282    as the file handles as returned by OS calls (like CreateFile) are
283    different from the libc file descriptors (like open). This function
284    translates system file handles to libc file handles.  FOR_WRITE
285    gives the direction of the handle.  */
286 int
287 translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
288 {
289 #ifdef HAVE_W32_SYSTEM
290   int x;
291
292   if (fd == GNUPG_INVALID_FD)
293     return -1;
294   
295   /* Note that _open_osfhandle is currently defined to take and return
296      a long.  */
297   x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
298   if (x == -1)
299     log_error ("failed to translate osfhandle %p\n", (void *) fd);
300   return x;
301 #else /*!HAVE_W32_SYSTEM */
302   (void)for_write;
303   return fd;
304 #endif
305 }
306
307 /* This is the same as translate_sys2libc_fd but takes an integer
308    which is assumed to be such an system handle.  */
309 int
310 translate_sys2libc_fd_int (int fd, int for_write)
311 {
312 #ifdef HAVE_W32_SYSTEM
313   if (fd <= 2)
314     return fd;  /* Do not do this for error, stdin, stdout, stderr. */
315
316   return translate_sys2libc_fd ((void*)fd, for_write);
317 #else
318   (void)for_write;
319   return fd;
320 #endif
321 }
322
323
324
325 /* Replacement for tmpfile().  This is required because the tmpfile
326    function of Windows' runtime library is broken, insecure, ignores
327    TMPDIR and so on.  In addition we create a file with an inheritable
328    handle.  */
329 FILE *
330 gnupg_tmpfile (void)
331 {
332 #ifdef HAVE_W32_SYSTEM
333   int attempts, n;
334   char buffer[MAX_PATH+7+12+1];
335   char *name, *p;
336   HANDLE file;
337   int pid = GetCurrentProcessId ();
338   unsigned int value;
339   int i;
340   SECURITY_ATTRIBUTES sec_attr;
341
342   memset (&sec_attr, 0, sizeof sec_attr );
343   sec_attr.nLength = sizeof sec_attr;
344   sec_attr.bInheritHandle = TRUE;
345
346   n = GetTempPath (MAX_PATH+1, buffer);
347   if (!n || n > MAX_PATH || strlen (buffer) > MAX_PATH)
348     {
349       errno = ENOENT;
350       return NULL;
351     }
352   p = buffer + strlen (buffer);
353   p = stpcpy (p, "_gnupg");
354   /* We try to create the directory but don't care about an error as
355      it may already exist and the CreateFile would throw an error
356      anyway.  */
357   CreateDirectory (buffer, NULL);
358   *p++ = '\\';
359   name = p;
360   for (attempts=0; attempts < 10; attempts++)
361     {
362       p = name;
363       value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
364       for (i=0; i < 8; i++)
365         {
366           *p++ = tohex (((value >> 28) & 0x0f));
367           value <<= 4;
368         }
369       strcpy (p, ".tmp");
370       file = CreateFile (buffer,
371                          GENERIC_READ | GENERIC_WRITE,
372                          0,
373                          &sec_attr,
374                          CREATE_NEW,
375                          FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
376                          NULL);
377       if (file != INVALID_HANDLE_VALUE)
378         {
379           FILE *fp;
380           int fd = _open_osfhandle ((long)file, 0);
381           if (fd == -1)
382             {
383               CloseHandle (file);
384               return NULL;
385             }
386           fp = fdopen (fd, "w+b");
387           if (!fp)
388             {
389               int save = errno;
390               close (fd);
391               errno = save;
392               return NULL;
393             }
394           return fp;
395         }
396       Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
397     }
398   errno = ENOENT;
399   return NULL;
400 #else /*!HAVE_W32_SYSTEM*/
401   return tmpfile ();
402 #endif /*!HAVE_W32_SYSTEM*/
403 }
404
405
406 /* Make sure that the standard file descriptors are opened. Obviously
407    some folks close them before an exec and the next file we open will
408    get one of them assigned and thus any output (i.e. diagnostics) end
409    up in that file (e.g. the trustdb).  Not actually a gpg problem as
410    this will hapen with almost all utilities when called in a wrong
411    way.  However we try to minimize the damage here and raise
412    awareness of the problem.
413
414    Must be called before we open any files! */
415 void
416 gnupg_reopen_std (const char *pgmname)
417 {  
418 #if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
419   struct stat statbuf;
420   int did_stdin = 0;
421   int did_stdout = 0;
422   int did_stderr = 0;
423   FILE *complain;
424
425   if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF)
426     {
427       if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
428         did_stdin = 1;
429       else
430         did_stdin = 2;
431     }
432   
433   if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
434     {
435       if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
436         did_stdout = 1;
437       else
438         did_stdout = 2;
439     }
440
441   if (fstat (STDERR_FILENO, &statbuf)==-1 && errno==EBADF)
442     {
443       if (open ("/dev/null", O_WRONLY) == STDERR_FILENO)
444         did_stderr = 1;
445       else
446         did_stderr = 2;
447     }
448
449   /* It's hard to log this sort of thing since the filehandle we would
450      complain to may be closed... */
451   if (!did_stderr)
452     complain = stderr;
453   else if (!did_stdout)
454     complain = stdout;
455   else
456     complain = NULL;
457
458   if (complain)
459     {
460       if (did_stdin == 1)
461         fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname);
462       if (did_stdout == 1)
463         fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname);
464       if (did_stderr == 1)
465         fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname);
466
467       if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
468         fprintf(complain,"%s: fatal: unable to reopen standard input,"
469                 " output, or error\n", pgmname);
470     }
471
472   if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
473     exit (3);
474 #else /* !(HAVE_STAT && !HAVE_W32_SYSTEM) */
475   (void)pgmname;
476 #endif
477 }
478
479
480 /* Hack required for Windows.  */
481 void 
482 gnupg_allow_set_foregound_window (pid_t pid)
483 {
484   if (!pid)
485     log_info ("%s called with invalid pid %lu\n",
486               "gnupg_allow_set_foregound_window", (unsigned long)pid);
487 #ifdef HAVE_W32_SYSTEM  
488   else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid))
489     log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
490                (unsigned long)pid, w32_strerror (-1));
491 #endif
492 }