Smartcard related updates
[gnupg.git] / common / exechelp-posix.c
1 /* exechelp.c - Fork and exec helpers for POSIX
2  * Copyright (C) 2004, 2007, 2008, 2009,
3  *               2010 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 #if defined(HAVE_W32_SYSTEM) || defined (HAVE_W32CE_SYSTEM)
24 #error This code is only used on POSIX
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <assert.h>
32 #ifdef HAVE_SIGNAL_H
33 # include <signal.h>
34 #endif
35 #include <unistd.h> 
36 #include <fcntl.h>
37
38 #ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth.  */
39 #undef HAVE_PTH
40 #undef USE_GNU_PTH
41 #endif
42
43 #ifdef USE_GNU_PTH      
44 #include <pth.h>
45 #endif
46 #include <sys/wait.h>
47
48 #ifdef HAVE_GETRLIMIT
49 #include <sys/time.h>
50 #include <sys/resource.h>
51 #endif /*HAVE_GETRLIMIT*/
52
53 #ifdef HAVE_STAT
54 # include <sys/stat.h>
55 #endif
56
57 #include "util.h"
58 #include "i18n.h"
59 #include "sysutils.h"
60 #include "exechelp.h"
61
62
63 /* We have the usual problem here: Some modules are linked against pth
64    and some are not.  However we want to use pth_fork and pth_waitpid
65    here. Using a weak symbol works but is not portable - we should
66    provide a an explicit dummy pth module instead of using the
67    pragma.  */ 
68 #pragma weak pth_fork
69 #pragma weak pth_waitpid
70
71
72 /* Return the maximum number of currently allowed open file
73    descriptors.  Only useful on POSIX systems but returns a value on
74    other systems too.  */
75 int
76 get_max_fds (void)
77 {
78   int max_fds = -1;
79 #ifdef HAVE_GETRLIMIT
80   struct rlimit rl;
81
82 # ifdef RLIMIT_NOFILE
83   if (!getrlimit (RLIMIT_NOFILE, &rl))
84     max_fds = rl.rlim_max;
85 # endif
86
87 # ifdef RLIMIT_OFILE
88   if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl))
89     max_fds = rl.rlim_max;
90
91 # endif
92 #endif /*HAVE_GETRLIMIT*/
93
94 #ifdef _SC_OPEN_MAX
95   if (max_fds == -1)
96     {
97       long int scres = sysconf (_SC_OPEN_MAX);
98       if (scres >= 0)
99         max_fds = scres;
100     }
101 #endif
102
103 #ifdef _POSIX_OPEN_MAX
104   if (max_fds == -1)
105     max_fds = _POSIX_OPEN_MAX;
106 #endif
107
108 #ifdef OPEN_MAX
109   if (max_fds == -1)
110     max_fds = OPEN_MAX;
111 #endif
112
113   if (max_fds == -1)
114     max_fds = 256;  /* Arbitrary limit.  */
115
116   return max_fds;
117 }
118
119
120 /* Close all file descriptors starting with descriptor FIRST.  If
121    EXCEPT is not NULL, it is expected to be a list of file descriptors
122    which shall not be closed.  This list shall be sorted in ascending
123    order with the end marked by -1.  */
124 void
125 close_all_fds (int first, int *except)
126 {
127   int max_fd = get_max_fds ();
128   int fd, i, except_start;
129
130   if (except)
131     {
132       except_start = 0;
133       for (fd=first; fd < max_fd; fd++)
134         {
135           for (i=except_start; except[i] != -1; i++)
136             {
137               if (except[i] == fd)
138                 {
139                   /* If we found the descriptor in the exception list
140                      we can start the next compare run at the next
141                      index because the exception list is ordered.  */
142                 except_start = i + 1;
143                 break;
144                 }
145             }
146           if (except[i] == -1)
147             close (fd);
148         }
149     }
150   else
151     {
152       for (fd=first; fd < max_fd; fd++)
153         close (fd);
154     }
155
156   gpg_err_set_errno (0);
157 }
158
159
160 /* Returns an array with all currently open file descriptors.  The end
161    of the array is marked by -1.  The caller needs to release this
162    array using the *standard free* and not with xfree.  This allow the
163    use of this fucntion right at startup even before libgcrypt has
164    been initialized.  Returns NULL on error and sets ERRNO
165    accordingly.  */
166 int *
167 get_all_open_fds (void)
168 {
169   int *array;
170   size_t narray;
171   int fd, max_fd, idx;
172 #ifndef HAVE_STAT
173   array = calloc (1, sizeof *array);
174   if (array)
175     array[0] = -1;
176 #else /*HAVE_STAT*/
177   struct stat statbuf;
178
179   max_fd = get_max_fds ();
180   narray = 32;  /* If you change this change also t-exechelp.c.  */
181   array = calloc (narray, sizeof *array);
182   if (!array)
183     return NULL;
184   
185   /* Note:  The list we return is ordered.  */
186   for (idx=0, fd=0; fd < max_fd; fd++)
187     if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
188       {
189         if (idx+1 >= narray)
190           {
191             int *tmp;
192
193             narray += (narray < 256)? 32:256;
194             tmp = realloc (array, narray * sizeof *array);
195             if (!tmp)
196               {
197                 free (array);
198                 return NULL;
199               }
200             array = tmp;
201           }
202         array[idx++] = fd;
203       }
204   array[idx] = -1;
205 #endif /*HAVE_STAT*/
206   return array;
207 }
208
209
210 /* The exec core used right after the fork. This will never return. */
211 static void
212 do_exec (const char *pgmname, const char *argv[],
213          int fd_in, int fd_out, int fd_err,
214          void (*preexec)(void) )
215 {
216   char **arg_list;
217   int i, j;
218   int fds[3];
219
220   fds[0] = fd_in;
221   fds[1] = fd_out;
222   fds[2] = fd_err;
223
224   /* Create the command line argument array.  */
225   i = 0;
226   if (argv)
227     while (argv[i])
228       i++;
229   arg_list = xcalloc (i+2, sizeof *arg_list);
230   arg_list[0] = strrchr (pgmname, '/');
231   if (arg_list[0])
232     arg_list[0]++;
233   else
234     arg_list[0] = xstrdup (pgmname);
235   if (argv)
236     for (i=0,j=1; argv[i]; i++, j++)
237       arg_list[j] = (char*)argv[i];
238
239   /* Assign /dev/null to unused FDs. */
240   for (i=0; i <= 2; i++)
241     {
242       if (fds[i] == -1 )
243         {
244           fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
245           if (fds[i] == -1)
246             log_fatal ("failed to open `%s': %s\n",
247                        "/dev/null", strerror (errno));
248         }
249     }
250
251   /* Connect the standard files.  */
252   for (i=0; i <= 2; i++)
253     {
254       if (fds[i] != i && dup2 (fds[i], i) == -1)
255         log_fatal ("dup2 std%s failed: %s\n",
256                    i==0?"in":i==1?"out":"err", strerror (errno));
257     }
258
259   /* Close all other files. */
260   close_all_fds (3, NULL);
261   
262   if (preexec)
263     preexec ();
264   execv (pgmname, arg_list);
265   /* No way to print anything, as we have closed all streams. */
266   _exit (127);
267 }
268
269
270 static gpg_error_t
271 do_create_pipe (int filedes[2])
272 {
273   gpg_error_t err = 0;
274
275   if (pipe (filedes) == -1)
276     {
277       err = gpg_error_from_syserror ();
278       filedes[0] = filedes[1] = -1;
279     }
280
281   return err;
282 }
283
284 /* Portable function to create a pipe.  Under Windows the write end is
285    inheritable.  */
286 gpg_error_t
287 gnupg_create_inbound_pipe (int filedes[2])
288 {
289   return do_create_pipe (filedes);
290 }
291
292
293 /* Portable function to create a pipe.  Under Windows the read end is
294    inheritable.  */
295 gpg_error_t
296 gnupg_create_outbound_pipe (int filedes[2])
297 {
298   return do_create_pipe (filedes);
299 }
300
301
302
303 static gpg_error_t
304 create_pipe_and_estream (int filedes[2], estream_t *r_fp,
305                          gpg_err_source_t errsource)
306 {
307   gpg_error_t err;
308
309   if (pipe (filedes) == -1)
310     {
311       err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
312       log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
313       filedes[0] = filedes[1] = -1;
314       *r_fp = NULL;
315       return err;
316     }
317
318   *r_fp = es_fdopen (filedes[0], "r");
319   if (!*r_fp)
320     {
321       err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
322       log_error (_("error creating a stream for a pipe: %s\n"),
323                  gpg_strerror (err));
324       close (filedes[0]);
325       close (filedes[1]);
326       filedes[0] = filedes[1] = -1;
327       return err;
328     }
329   return 0;
330 }
331   
332
333
334 /* Fork and exec the PGMNAME, see exechelp.h for details.  */
335 gpg_error_t
336 gnupg_spawn_process (const char *pgmname, const char *argv[],
337                      gpg_err_source_t errsource,
338                      void (*preexec)(void), unsigned int flags,
339                      estream_t infp,
340                      estream_t *r_outfp,
341                      estream_t *r_errfp,
342                      pid_t *pid)
343 {
344   gpg_error_t err;
345   int infd = -1;
346   int outpipe[2] = {-1, -1};
347   int errpipe[2] = {-1, -1};
348   estream_t outfp = NULL;
349   estream_t errfp = NULL;
350
351   (void)flags; /* Currently not used.  */
352
353   if (r_outfp)
354     *r_outfp = NULL;
355   if (r_errfp)
356     *r_errfp = NULL;
357   *pid = (pid_t)(-1); /* Always required.  */
358
359   if (infp)
360     {
361       es_fflush (infp);
362       es_rewind (infp);
363       infd = es_fileno (infp);
364       if (infd == -1)
365         return gpg_err_make (errsource, GPG_ERR_INV_VALUE);
366     }
367
368   if (r_outfp)
369     {
370       err = create_pipe_and_estream (outpipe, &outfp, errsource);
371       if (err)
372         return err;
373     }
374
375   if (r_errfp)
376     {
377       err = create_pipe_and_estream (errpipe, &errfp, errsource);
378       if (err)
379         {
380           if (outfp)
381             es_fclose (outfp);
382           else if (outpipe[0] != -1)
383             close (outpipe[0]);
384           if (outpipe[1] != -1)
385             close (outpipe[1]);
386           return err;
387         }
388     }
389
390
391 #ifdef USE_GNU_PTH      
392   *pid = pth_fork? pth_fork () : fork ();
393 #else
394   *pid = fork ();
395 #endif
396   if (*pid == (pid_t)(-1))
397     {
398       err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
399       log_error (_("error forking process: %s\n"), gpg_strerror (err));
400
401       if (outfp)
402         es_fclose (outfp);
403       else if (outpipe[0] != -1)
404         close (outpipe[0]);
405       if (outpipe[1] != -1)
406         close (outpipe[1]);
407
408       if (errfp)
409         es_fclose (errfp);
410       else if (errpipe[0] != -1)
411         close (errpipe[0]);
412       if (errpipe[1] != -1)
413         close (errpipe[1]);
414       return err;
415     }
416
417   if (!*pid)
418     { 
419       /* This is the child. */
420       gcry_control (GCRYCTL_TERM_SECMEM);
421       es_fclose (outfp);
422       es_fclose (errfp);
423       do_exec (pgmname, argv, infd, outpipe[1], errpipe[1], preexec);
424       /*NOTREACHED*/
425     }
426
427   /* This is the parent. */
428   if (outpipe[1] != -1)
429     close (outpipe[1]);
430   if (errpipe[1] != -1)
431     close (errpipe[1]);
432
433   if (r_outfp)
434     *r_outfp = outfp;
435   if (r_errfp)
436     *r_errfp = errfp;
437
438   return 0;
439 }
440
441
442
443 /* Simplified version of gnupg_spawn_process.  This function forks and
444    then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout
445    and ERRFD to stderr (any of them may be -1 to connect them to
446    /dev/null).  The arguments for the process are expected in the NULL
447    terminated array ARGV.  The program name itself should not be
448    included there.  Calling gnupg_wait_process is required.
449
450    Returns 0 on success or an error code. */
451 gpg_error_t
452 gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
453                         int infd, int outfd, int errfd, pid_t *pid)
454 {
455   gpg_error_t err;
456
457 #ifdef USE_GNU_PTH      
458   *pid = pth_fork? pth_fork () : fork ();
459 #else
460   *pid = fork ();
461 #endif
462   if (*pid == (pid_t)(-1))
463     {
464       err = gpg_error_from_syserror ();
465       log_error (_("error forking process: %s\n"), strerror (errno));
466       return err;
467     }
468
469   if (!*pid)
470     { 
471       gcry_control (GCRYCTL_TERM_SECMEM);
472       /* Run child. */
473       do_exec (pgmname, argv, infd, outfd, errfd, NULL);
474       /*NOTREACHED*/
475     }
476
477   return 0;
478 }
479
480
481 /* See exechelp.h for the description.  */
482 gpg_error_t
483 gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
484 {
485   gpg_err_code_t ec;
486   int i, status;
487
488   if (r_exitcode)
489     *r_exitcode = -1;
490
491   if (pid == (pid_t)(-1))
492     return gpg_error (GPG_ERR_INV_VALUE);
493
494 #ifdef USE_GNU_PTH
495   if (pth_waitpid)
496     i = pth_waitpid (pid, &status, hang? 0:WNOHANG);
497   else
498 #endif
499     {
500       while ((i=waitpid (pid, &status, hang? 0:WNOHANG)) == (pid_t)(-1)
501              && errno == EINTR)
502         ;
503     }
504   
505   if (i == (pid_t)(-1))
506     {
507       ec = gpg_err_code_from_errno (errno);
508       log_error (_("waiting for process %d to terminate failed: %s\n"),
509                  (int)pid, strerror (errno));
510     }
511   else if (!i)
512     {
513       ec = GPG_ERR_TIMEOUT; /* Still running.  */
514     }
515   else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
516     {
517       log_error (_("error running `%s': probably not installed\n"), pgmname);
518       ec = GPG_ERR_CONFIGURATION;
519     }
520   else if (WIFEXITED (status) && WEXITSTATUS (status))
521     {
522       if (!r_exitcode)
523         log_error (_("error running `%s': exit status %d\n"), pgmname,
524                    WEXITSTATUS (status));
525       else
526         *r_exitcode = WEXITSTATUS (status);
527       ec = GPG_ERR_GENERAL;
528     }
529   else if (!WIFEXITED (status))
530     {
531       log_error (_("error running `%s': terminated\n"), pgmname);
532       ec = GPG_ERR_GENERAL;
533     }
534   else 
535     {
536       if (r_exitcode)
537         *r_exitcode = 0;
538       ec = 0;
539     }
540
541   return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
542 }
543
544
545 void
546 gnupg_release_process (pid_t pid)
547 {
548   (void)pid;
549 }
550
551
552 /* Spawn a new process and immediately detach from it.  The name of
553    the program to exec is PGMNAME and its arguments are in ARGV (the
554    programname is automatically passed as first argument).
555    Environment strings in ENVP are set.  An error is returned if
556    pgmname is not executable; to make this work it is necessary to
557    provide an absolute file name.  All standard file descriptors are
558    connected to /dev/null. */
559 gpg_error_t
560 gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
561                               const char *envp[] )
562 {
563   pid_t pid;
564   int i;
565
566   if (getuid() != geteuid())
567     return gpg_error (GPG_ERR_BUG);
568
569   if (access (pgmname, X_OK))
570     return gpg_error_from_syserror ();
571
572 #ifdef USE_GNU_PTH      
573   pid = pth_fork? pth_fork () : fork ();
574 #else
575   pid = fork ();
576 #endif
577   if (pid == (pid_t)(-1))
578     {
579       log_error (_("error forking process: %s\n"), strerror (errno));
580       return gpg_error_from_syserror ();
581     }
582   if (!pid)
583     {
584       pid_t pid2;
585
586       gcry_control (GCRYCTL_TERM_SECMEM);
587       if (setsid() == -1 || chdir ("/"))
588         _exit (1);
589
590       pid2 = fork (); /* Double fork to let init take over the new child. */
591       if (pid2 == (pid_t)(-1))
592         _exit (1);
593       if (pid2)
594         _exit (0);  /* Let the parent exit immediately. */
595
596       if (envp)
597         for (i=0; envp[i]; i++)
598           putenv (xstrdup (envp[i]));
599       
600       do_exec (pgmname, argv, -1, -1, -1, NULL);
601
602       /*NOTREACHED*/
603     }
604   
605   if (waitpid (pid, NULL, 0) == -1)
606     log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
607                strerror (errno));
608
609   return 0;
610 }
611
612
613 /* Kill a process; that is send an appropriate signal to the process.
614    gnupg_wait_process must be called to actually remove the process
615    from the system.  An invalid PID is ignored.  */
616 void
617 gnupg_kill_process (pid_t pid)
618 {
619   if (pid != (pid_t)(-1))
620     {
621       kill (pid, SIGTERM); 
622     }
623 }