Fixed card key generation of gpg2.
[gnupg.git] / common / exechelp.c
1 /* exechelp.c - fork and exec helpers
2  *      Copyright (C) 2004 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <signal.h>
28 #include <unistd.h> 
29 #include <fcntl.h>
30
31 #ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth.  */
32 #undef HAVE_PTH
33 #undef USE_GNU_PTH
34 #endif
35
36 #ifdef USE_GNU_PTH      
37 #include <pth.h>
38 #endif
39 #ifndef HAVE_W32_SYSTEM
40 #include <sys/wait.h>
41 #endif
42
43 #include "util.h"
44 #include "i18n.h"
45 #include "exechelp.h"
46
47 /* Define to 1 do enable debugging.  */
48 #define DEBUG_W32_SPAWN 1
49
50
51 #ifdef _POSIX_OPEN_MAX
52 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
53 #else
54 #define MAX_OPEN_FDS 20
55 #endif
56
57 /* We have the usual problem here: Some modules are linked against pth
58    and some are not.  However we want to use pth_fork and pth_waitpid
59    here. Using a weak symbol works but is not portable - we should
60    provide a an explicit dummy pth module instead of using the
61    pragma.  */ 
62 #ifndef _WIN32
63 #pragma weak pth_fork
64 #pragma weak pth_waitpid
65 #endif
66
67
68 #ifdef HAVE_W32_SYSTEM
69 /* We assume that a HANDLE can be represented by an int which should
70    be true for all i386 systems (HANDLE is defined as void *) and
71    these are the only systems for which Windows is available.  Further
72    we assume that -1 denotes an invalid handle.  */
73 # define fd_to_handle(a)  ((HANDLE)(a))
74 # define handle_to_fd(a)  ((int)(a))
75 # define pid_to_handle(a) ((HANDLE)(a))
76 # define handle_to_pid(a) ((int)(a))
77 #endif
78
79
80 #ifdef HAVE_W32_SYSTEM
81 /* Helper function to build_w32_commandline. */
82 static char *
83 build_w32_commandline_copy (char *buffer, const char *string)
84 {
85   char *p = buffer;
86   const char *s;
87
88   if (!*string) /* Empty string. */
89     p = stpcpy (p, "\"\"");
90   else if (strpbrk (string, " \t\n\v\f\""))
91     {
92       /* Need top do some kind of quoting.  */
93       p = stpcpy (p, "\"");
94       for (s=string; *s; s++)
95         {
96           *p++ = *s;
97           if (*s == '\"')
98             *p++ = *s;
99         }
100       *p++ = '\"';
101       *p = 0;
102     }
103   else
104     p = stpcpy (p, string);
105
106   return p;
107 }
108
109 /* Build a command line for use with W32's CreateProcess.  On success
110    CMDLINE gets the address of a newly allocated string.  */
111 static gpg_error_t
112 build_w32_commandline (const char *pgmname, const char * const *argv, 
113                        char **cmdline)
114 {
115   int i, n;
116   const char *s;
117   char *buf, *p;
118
119   *cmdline = NULL;
120   n = 0;
121   s = pgmname;
122   n += strlen (s) + 1 + 2;  /* (1 space, 2 quoting */
123   for (; *s; s++)
124     if (*s == '\"')
125       n++;  /* Need to double inner quotes.  */
126   for (i=0; (s=argv[i]); i++)
127     {
128       n += strlen (s) + 1 + 2;  /* (1 space, 2 quoting */
129       for (; *s; s++)
130         if (*s == '\"')
131           n++;  /* Need to double inner quotes.  */
132     }
133   n++;
134
135   buf = p = xtrymalloc (n);
136   if (!buf)
137     return gpg_error_from_syserror ();
138
139   p = build_w32_commandline_copy (p, pgmname);
140   for (i=0; argv[i]; i++) 
141     {
142       *p++ = ' ';
143       p = build_w32_commandline_copy (p, argv[i]);
144     }
145
146   *cmdline= buf;
147   return 0;
148 }
149 #endif /*HAVE_W32_SYSTEM*/
150
151
152 #ifdef HAVE_W32_SYSTEM
153 /* Create  pipe where the write end is inheritable.  */
154 static int
155 create_inheritable_pipe (int filedes[2])
156 {
157   HANDLE r, w, h;
158   SECURITY_ATTRIBUTES sec_attr;
159
160   memset (&sec_attr, 0, sizeof sec_attr );
161   sec_attr.nLength = sizeof sec_attr;
162   sec_attr.bInheritHandle = FALSE;
163     
164   if (!CreatePipe (&r, &w, &sec_attr, 0))
165     return -1;
166
167   if (!DuplicateHandle (GetCurrentProcess(), w,
168                         GetCurrentProcess(), &h, 0,
169                         TRUE, DUPLICATE_SAME_ACCESS ))
170     {
171       log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
172       CloseHandle (r);
173       CloseHandle (w);
174       return -1;
175     }
176   CloseHandle (w);
177   w = h;
178
179   filedes[0] = handle_to_fd (r);
180   filedes[1] = handle_to_fd (w);
181   return 0;
182 }
183 #endif /*HAVE_W32_SYSTEM*/
184
185
186 #ifndef HAVE_W32_SYSTEM
187 /* The exec core used right after the fork. This will never return. */
188 static void
189 do_exec (const char *pgmname, const char *argv[],
190          int fd_in, int fd_out, int fd_err,
191          void (*preexec)(void) )
192 {
193   char **arg_list;
194   int n, i, j;
195   int fds[3];
196
197   fds[0] = fd_in;
198   fds[1] = fd_out;
199   fds[2] = fd_err;
200
201   /* Create the command line argument array.  */
202   i = 0;
203   if (argv)
204     while (argv[i])
205       i++;
206   arg_list = xcalloc (i+2, sizeof *arg_list);
207   arg_list[0] = strrchr (pgmname, '/');
208   if (arg_list[0])
209     arg_list[0]++;
210   else
211     arg_list[0] = xstrdup (pgmname);
212   if (argv)
213     for (i=0,j=1; argv[i]; i++, j++)
214       arg_list[j] = (char*)argv[i];
215
216   /* Connect the standard files. */
217   for (i=0; i <= 2; i++)
218     {
219       if (fds[i] == -1 )
220         {
221           fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
222           if (fds[i] == -1)
223             log_fatal ("failed to open `%s': %s\n",
224                        "/dev/null", strerror (errno));
225         }
226       else if (fds[i] != i && dup2 (fds[i], i) == -1)
227         log_fatal ("dup2 std%s failed: %s\n",
228                    i==0?"in":i==1?"out":"err", strerror (errno));
229     }
230
231   /* Close all other files. */
232   n = sysconf (_SC_OPEN_MAX);
233   if (n < 0)
234     n = MAX_OPEN_FDS;
235   for (i=3; i < n; i++)
236     close(i);
237   errno = 0;
238   
239   if (preexec)
240     preexec ();
241   execv (pgmname, arg_list);
242   /* No way to print anything, as we have closed all streams. */
243   _exit (127);
244 }
245 #endif /*!HAVE_W32_SYSTEM*/
246
247
248 /* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
249    stdin, write the output to OUTFILE, return a new stream in
250    STATUSFILE for stderr and the pid of the process in PID. The
251    arguments for the process are expected in the NULL terminated array
252    ARGV.  The program name itself should not be included there.  if
253    PREEXEC is not NULL, that function will be called right before the
254    exec.
255
256    Returns 0 on success or an error code. */
257 gpg_error_t
258 gnupg_spawn_process (const char *pgmname, const char *argv[],
259                      FILE *infile, FILE *outfile,
260                      void (*preexec)(void),
261                      FILE **statusfile, pid_t *pid)
262 {
263 #ifdef HAVE_W32_SYSTEM
264   gpg_error_t err;
265   SECURITY_ATTRIBUTES sec_attr;
266   PROCESS_INFORMATION pi = 
267     {
268       NULL,      /* Returns process handle.  */
269       0,         /* Returns primary thread handle.  */
270       0,         /* Returns pid.  */
271       0          /* Returns tid.  */
272     };
273   STARTUPINFO si;
274   int cr_flags;
275   char *cmdline;
276   int fd, fdout, rp[2];
277
278   /* Setup return values.  */
279   *statusfile = NULL;
280   *pid = (pid_t)(-1);
281   fflush (infile);
282   rewind (infile);
283   fd = _get_osfhandle (fileno (infile));
284   fdout = _get_osfhandle (fileno (outfile));
285   if (fd == -1 || fdout == -1)
286     log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
287
288   /* Prepare security attributes.  */
289   memset (&sec_attr, 0, sizeof sec_attr );
290   sec_attr.nLength = sizeof sec_attr;
291   sec_attr.bInheritHandle = FALSE;
292   
293   /* Build the command line.  */
294   err = build_w32_commandline (pgmname, argv, &cmdline);
295   if (err)
296     return err; 
297
298   /* Create a pipe.  */
299   if (create_inheritable_pipe (rp))
300     {
301       err = gpg_error (GPG_ERR_GENERAL);
302       log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
303       xfree (cmdline);
304       return err;
305     }
306   
307   /* Start the process.  Note that we can't run the PREEXEC function
308      because this would change our own environment. */
309   memset (&si, 0, sizeof si);
310   si.cb = sizeof (si);
311   si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
312   si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
313   si.hStdInput  = fd_to_handle (fd);
314   si.hStdOutput = fd_to_handle (fdout);
315   si.hStdError  = fd_to_handle (rp[1]);
316
317   cr_flags = (CREATE_DEFAULT_ERROR_MODE
318               | GetPriorityClass (GetCurrentProcess ())
319               | CREATE_SUSPENDED); 
320   log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline);
321   if (!CreateProcess (pgmname,       /* Program to start.  */
322                       cmdline,       /* Command line arguments.  */
323                       &sec_attr,     /* Process security attributes.  */
324                       &sec_attr,     /* Thread security attributes.  */
325                       TRUE,          /* Inherit handles.  */
326                       cr_flags,      /* Creation flags.  */
327                       NULL,          /* Environment.  */
328                       NULL,          /* Use current drive/directory.  */
329                       &si,           /* Startup information. */
330                       &pi            /* Returns process information.  */
331                       ))
332     {
333       log_error ("CreateProcess failed: %s\n", w32_strerror (-1));
334       xfree (cmdline);
335       CloseHandle (fd_to_handle (rp[0]));
336       CloseHandle (fd_to_handle (rp[1]));
337       return gpg_error (GPG_ERR_GENERAL);
338     }
339   xfree (cmdline);
340   cmdline = NULL;
341
342   /* Close the other end of the pipe.  */
343   CloseHandle (fd_to_handle (rp[1]));
344   
345   log_debug ("CreateProcess ready: hProcess=%p hThread=%p"
346              " dwProcessID=%d dwThreadId=%d\n",
347              pi.hProcess, pi.hThread,
348              (int) pi.dwProcessId, (int) pi.dwThreadId);
349
350   /* Process has been created suspended; resume it now. */
351   ResumeThread (pi.hThread);
352   CloseHandle (pi.hThread); 
353
354   {
355     int x;
356
357     x = _open_osfhandle (rp[0], 0);
358     if (x == -1)
359       log_error ("failed to translate osfhandle %p\n", (void*)rp[0] );
360     else 
361       {
362         log_debug ("_open_osfhandle %p yields %d\n", (void*)fd, x );
363         *statusfile = fdopen (x, "r");
364       }
365   }
366   if (!*statusfile)
367     {
368       err = gpg_error_from_syserror ();
369       log_error (_("can't fdopen pipe for reading: %s\n"), gpg_strerror (err));
370       CloseHandle (pi.hProcess);
371       return err;
372     }
373
374   *pid = handle_to_pid (pi.hProcess);
375   return 0;
376
377 #else /* !HAVE_W32_SYSTEM */
378   gpg_error_t err;
379   int fd, fdout, rp[2];
380
381   *statusfile = NULL;
382   *pid = (pid_t)(-1);
383   fflush (infile);
384   rewind (infile);
385   fd = fileno (infile);
386   fdout = fileno (outfile);
387   if (fd == -1 || fdout == -1)
388     log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
389
390   if (pipe (rp) == -1)
391     {
392       err = gpg_error_from_syserror ();
393       log_error (_("error creating a pipe: %s\n"), strerror (errno));
394       return err;
395     }
396
397 #ifdef USE_GNU_PTH      
398   *pid = pth_fork? pth_fork () : fork ();
399 #else
400   *pid = fork ();
401 #endif
402   if (*pid == (pid_t)(-1))
403     {
404       err = gpg_error_from_syserror ();
405       log_error (_("error forking process: %s\n"), strerror (errno));
406       close (rp[0]);
407       close (rp[1]);
408       return err;
409     }
410
411   if (!*pid)
412     { 
413       gcry_control (GCRYCTL_TERM_SECMEM);
414       /* Run child. */
415       do_exec (pgmname, argv, fd, fdout, rp[1], preexec);
416       /*NOTREACHED*/
417     }
418
419   /* Parent. */
420   close (rp[1]);
421
422   *statusfile = fdopen (rp[0], "r");
423   if (!*statusfile)
424     {
425       err = gpg_error_from_syserror ();
426       log_error (_("can't fdopen pipe for reading: %s\n"), strerror (errno));
427       kill (*pid, SIGTERM);
428       *pid = (pid_t)(-1);
429       return err;
430     }
431
432   return 0;
433 #endif /* !HAVE_W32_SYSTEM */
434 }
435
436
437 /* Wait for the process identified by PID to terminate. PGMNAME should
438    be the same as suplieed to the spawn fucntion and is only used for
439    diagnostics. Returns 0 if the process succeded, GPG_ERR_GENERAL for
440    any failures of the spawned program or other error codes.*/
441 gpg_error_t
442 gnupg_wait_process (const char *pgmname, pid_t pid)
443 {
444   gpg_err_code_t ec;
445
446 #ifdef HAVE_W32_SYSTEM
447   HANDLE proc = fd_to_handle (pid);
448   int code;
449   DWORD exc;
450
451   if (pid == (pid_t)(-1))
452     return gpg_error (GPG_ERR_INV_VALUE);
453
454   /* FIXME: We should do a pth_waitpid here.  However this has not yet
455      been implemented.  A special W32 pth system call would even be
456      better.  */
457   code = WaitForSingleObject (proc, INFINITE);
458   switch (code) 
459     {
460       case WAIT_FAILED:
461         log_error (_("waiting for process %d to terminate failed: %s\n"),
462                    (int)pid, w32_strerror (-1));
463         ec = GPG_ERR_GENERAL;
464         break;
465
466       case WAIT_OBJECT_0:
467         if (!GetExitCodeProcess (proc, &exc))
468           {
469             log_error (_("error getting exit code of process %d: %s\n"),
470                          (int)pid, w32_strerror (-1) );
471             ec = GPG_ERR_GENERAL;
472           }
473         else if (exc)
474           {
475             log_error (_("error running `%s': exit status %d\n"),
476                        pgmname, (int)exc );
477             ec = GPG_ERR_GENERAL;
478           }
479         else
480           ec = 0;
481         break;
482
483       default:
484         log_error ("WaitForSingleObject returned unexpected "
485                    "code %d for pid %d\n", code, (int)pid );
486         ec = GPG_ERR_GENERAL;
487         break;
488     }
489
490 #else /* !HAVE_W32_SYSTEM */
491   int i, status;
492
493   if (pid == (pid_t)(-1))
494     return gpg_error (GPG_ERR_INV_VALUE);
495
496 #ifdef USE_GNU_PTH
497   i = pth_waitpid ? pth_waitpid (pid, &status, 0) : waitpid (pid, &status, 0);
498 #else
499   while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
500     ;
501 #endif
502   if (i == (pid_t)(-1))
503     {
504       log_error (_("waiting for process %d to terminate failed: %s\n"),
505                  (int)pid, strerror (errno));
506       ec = gpg_err_code_from_errno (errno);
507     }
508   else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
509     {
510       log_error (_("error running `%s': probably not installed\n"), pgmname);
511       ec = GPG_ERR_CONFIGURATION;
512     }
513   else if (WIFEXITED (status) && WEXITSTATUS (status))
514     {
515       log_error (_("error running `%s': exit status %d\n"), pgmname,
516                  WEXITSTATUS (status));
517       ec = GPG_ERR_GENERAL;
518     }
519   else if (!WIFEXITED (status))
520     {
521       log_error (_("error running `%s': terminated\n"), pgmname);
522       ec = GPG_ERR_GENERAL;
523     }
524   else 
525     ec = 0;
526 #endif /* !HAVE_W32_SYSTEM */
527
528   return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
529
530 }
531
532
533 /* Spawn a new process and immediatley detach from it.  The name of
534    the program to exec is PGMNAME and its arguments are in ARGV (the
535    programname is automatically passed as first argument).
536    Environment strings in ENVP are set.  An error is returned if
537    pgmname is not executable; to make this work it is necessary to
538    provide an absolute file name.  All standard file descriptors are
539    connected to /dev/null. */
540 gpg_error_t
541 gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
542                               const char *envp[] )
543 {
544 #ifdef HAVE_W32_SYSTEM
545   gpg_error_t err;
546   SECURITY_ATTRIBUTES sec_attr;
547   PROCESS_INFORMATION pi = 
548     {
549       NULL,      /* Returns process handle.  */
550       0,         /* Returns primary thread handle.  */
551       0,         /* Returns pid.  */
552       0          /* Returns tid.  */
553     };
554   STARTUPINFO si;
555   int cr_flags;
556   char *cmdline;
557
558
559   /* FIXME: We don't make use of ENVP yet.  It is currently only used
560      to pass the GPG_AGENT_INFO variable to gpg-agent.  As the default
561      on windows is to use a standard socket, this does not really
562      matter.  */
563
564
565   if (access (pgmname, X_OK))
566     return gpg_error_from_syserror ();
567
568   /* Prepare security attributes.  */
569   memset (&sec_attr, 0, sizeof sec_attr );
570   sec_attr.nLength = sizeof sec_attr;
571   sec_attr.bInheritHandle = FALSE;
572   
573   /* Build the command line.  */
574   err = build_w32_commandline (pgmname, argv, &cmdline);
575   if (err)
576     return err; 
577
578   /* Start the process.  */
579   memset (&si, 0, sizeof si);
580   si.cb = sizeof (si);
581   si.dwFlags = STARTF_USESHOWWINDOW;
582   si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
583
584   cr_flags = (CREATE_DEFAULT_ERROR_MODE
585               | GetPriorityClass (GetCurrentProcess ())
586               | CREATE_NEW_PROCESS_GROUP
587               | DETACHED_PROCESS); 
588   log_debug ("CreateProcess(detached), path=`%s' cmdline=`%s'\n",
589              pgmname, cmdline);
590   if (!CreateProcess (pgmname,       /* Program to start.  */
591                       cmdline,       /* Command line arguments.  */
592                       &sec_attr,     /* Process security attributes.  */
593                       &sec_attr,     /* Thread security attributes.  */
594                       FALSE,         /* Inherit handles.  */
595                       cr_flags,      /* Creation flags.  */
596                       NULL,          /* Environment.  */
597                       NULL,          /* Use current drive/directory.  */
598                       &si,           /* Startup information. */
599                       &pi            /* Returns process information.  */
600                       ))
601     {
602       log_error ("CreateProcess(detached) failed: %s\n", w32_strerror (-1));
603       xfree (cmdline);
604       return gpg_error (GPG_ERR_GENERAL);
605     }
606   xfree (cmdline);
607   cmdline = NULL;
608
609   log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p"
610              " dwProcessID=%d dwThreadId=%d\n",
611              pi.hProcess, pi.hThread,
612              (int) pi.dwProcessId, (int) pi.dwThreadId);
613
614   CloseHandle (pi.hThread); 
615
616   return 0;
617
618 #else
619   pid_t pid;
620   int i;
621
622   if (getuid() != geteuid())
623     return gpg_error (GPG_ERR_BUG);
624
625   if (access (pgmname, X_OK))
626     return gpg_error_from_syserror ();
627
628 #ifdef USE_GNU_PTH      
629   pid = pth_fork? pth_fork () : fork ();
630 #else
631   pid = fork ();
632 #endif
633   if (pid == (pid_t)(-1))
634     {
635       log_error (_("error forking process: %s\n"), strerror (errno));
636       return gpg_error_from_syserror ();
637     }
638   if (!pid)
639     {
640       gcry_control (GCRYCTL_TERM_SECMEM);
641       if (setsid() == -1 || chdir ("/"))
642         _exit (1);
643       pid = fork (); /* Double fork to let init takes over the new child. */
644       if (pid == (pid_t)(-1))
645         _exit (1);
646       if (pid)
647         _exit (0);  /* Let the parent exit immediately. */
648
649       if (envp)
650         for (i=0; envp[i]; i++)
651           putenv (xstrdup (envp[i]));
652       
653       do_exec (pgmname, argv, -1, -1, -1, NULL);
654
655       /*NOTREACHED*/
656     }
657   
658   if (waitpid (pid, NULL, 0) == -1)
659     log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
660                strerror (errno));
661
662   return 0;
663 #endif /* !HAVE_W32_SYSTEM*/
664 }