Removed audit.h cruft which forced us to link against libksba.
[gnupg.git] / g13 / call-gpg.c
1 /* call-gpg.c - Communication with the GPG
2  * Copyright (C) 2009 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 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <time.h>
26 #include <assert.h>
27 #include <pth.h>
28
29 #include "g13.h"
30 #include <assuan.h>
31 #include "i18n.h"
32 #include "call-gpg.h"
33 #include "utils.h"
34 #include "../common/exechelp.h"
35
36
37 \f
38 /* Fire up a new GPG.  Handle the server's initial greeting.  Returns
39    0 on success and stores the assuan context at R_CTX.  */
40 static gpg_error_t
41 start_gpg (ctrl_t ctrl, int input_fd, int output_fd, assuan_context_t *r_ctx)
42 {
43   gpg_error_t err;
44   assuan_context_t ctx = NULL;
45   const char *pgmname;
46   const char *argv[7];
47   int no_close_list[5];
48   int i;
49   char line[ASSUAN_LINELENGTH];
50
51   (void)ctrl;
52
53   *r_ctx = NULL;
54
55   err = assuan_new (&ctx);
56   if (err)
57     {
58       log_error ("can't allocate assuan context: %s\n", gpg_strerror (err));
59       return err;
60     }
61
62   /* The first time we are used, intialize the gpg_program variable.  */
63   if ( !opt.gpg_program || !*opt.gpg_program )
64     opt.gpg_program = gnupg_module_name (GNUPG_MODULE_NAME_GPG);
65
66   if (opt.verbose)
67     log_info (_("no running gpg - starting `%s'\n"), opt.gpg_program);
68       
69   /* Compute argv[0].  */
70   if ( !(pgmname = strrchr (opt.gpg_program, '/')))
71     pgmname = opt.gpg_program;
72   else
73     pgmname++;
74
75   if (fflush (NULL))
76     {
77       err = gpg_error_from_syserror ();
78       log_error ("error flushing pending output: %s\n", gpg_strerror (err));
79       return err;
80     }
81
82   i = 0;
83   argv[i++] = pgmname;
84   argv[i++] = "--server";
85   if ((opt.debug & 1024))
86     argv[i++] = "--debug=1024";
87   argv[i++] = "-z";
88   argv[i++] = "0";
89   argv[i++] = NULL;
90   
91   i = 0;
92   if (log_get_fd () != -1)
93     no_close_list[i++] = log_get_fd ();
94   no_close_list[i++] = fileno (stderr);
95   if (input_fd != -1)
96     no_close_list[i++] = input_fd;
97   if (output_fd != -1)
98     no_close_list[i++] = output_fd;
99   no_close_list[i] = -1;
100
101   /* Connect to GPG and perform initial handshaking.  */
102   err = assuan_pipe_connect (ctx, opt.gpg_program, argv, no_close_list);
103   if (err)
104     {
105       assuan_release (ctx);
106       log_error ("can't connect to GPG: %s\n", gpg_strerror (err));
107       return gpg_error (GPG_ERR_NO_ENGINE);
108     }
109
110   if (input_fd != -1)
111     {
112       snprintf (line, sizeof line, "INPUT FD=%d", input_fd);
113       err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
114       if (err)
115         {
116           assuan_release (ctx);
117           log_error ("error sending INPUT command: %s\n", gpg_strerror (err));
118           return err;
119         }
120     }
121
122   if (output_fd != -1)
123     {
124       snprintf (line, sizeof line, "OUTPUT FD=%d", output_fd);
125       err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
126       if (err)
127         {
128           assuan_release (ctx);
129           log_error ("error sending OUTPUT command: %s\n", gpg_strerror (err));
130           return err;
131         }
132     }
133
134   *r_ctx = ctx;
135   
136   if (DBG_ASSUAN)
137     log_debug ("connection to GPG established\n");
138   return 0;
139 }
140
141
142 /* Release the assuan context created by start_gpg.  */
143 static void
144 release_gpg (assuan_context_t ctx)
145 {
146   assuan_release (ctx);
147 }
148
149
150 \f
151 /* The data passed to the writer_thread.  */ 
152 struct writer_thread_parms
153 {
154   int fd;
155   const void *data;
156   size_t datalen;
157   gpg_error_t *err_addr;
158 };
159
160
161 /* The thread started by start_writer.  */
162 static void *
163 writer_thread (void *arg)
164 {
165   struct writer_thread_parms *parm = arg;
166   const char *buffer = parm->data;
167   size_t length = parm->datalen;
168
169   while (length)
170     {
171       ssize_t nwritten;
172
173       nwritten = pth_write (parm->fd, buffer, length < 4096? length:4096);
174       if (nwritten < 0)
175         {
176           if (errno == EINTR)
177             continue;
178           *parm->err_addr = gpg_error_from_syserror ();
179           break; /* Write error.  */
180         }
181       length -= nwritten;
182       buffer += nwritten;
183     }
184
185   if (close (parm->fd))
186     log_error ("closing writer fd %d failed: %s\n", parm->fd, strerror (errno));
187   xfree (parm);
188   return NULL;
189 }
190
191
192 /* Fire up a thread to send (DATA,DATALEN) to the file descriptor FD.
193    On success the thread receives the ownership over FD.  The thread
194    ID is stored at R_TID.  WRITER_ERR is the address of an gpg_error_t
195    variable to receive a possible write error after the thread has
196    finished.  */
197 static gpg_error_t
198 start_writer (int fd, const void *data, size_t datalen, 
199               pth_t *r_tid, gpg_error_t *err_addr)
200 {
201   gpg_error_t err;
202   struct writer_thread_parms *parm;
203   pth_attr_t tattr;
204   pth_t tid;
205
206   *r_tid = NULL;
207   *err_addr = 0;
208
209   parm = xtrymalloc (sizeof *parm);
210   if (!parm)
211     return gpg_error_from_syserror ();
212   parm->fd = fd;
213   parm->data = data;
214   parm->datalen = datalen;
215   parm->err_addr = err_addr;
216
217   tattr = pth_attr_new ();
218   pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1);
219   pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024);
220   pth_attr_set (tattr, PTH_ATTR_NAME, "fd-writer");
221
222   tid = pth_spawn (tattr, writer_thread, parm);
223   if (!tid)
224     {
225       err = gpg_error_from_syserror ();
226       log_error ("error spawning writer thread: %s\n", gpg_strerror (err));
227     }
228   else
229     {
230       err = 0;
231       *r_tid = tid;
232     }
233   pth_attr_destroy (tattr);
234
235   return err;
236 }
237
238
239 \f
240 /* The data passed to the reader_thread.  */ 
241 struct reader_thread_parms
242 {
243   int fd;
244   membuf_t *mb;
245   gpg_error_t *err_addr;
246 };
247
248
249 /* The thread started by start_reader.  */
250 static void *
251 reader_thread (void *arg)
252 {
253   struct reader_thread_parms *parm = arg;
254   char buffer[4096];
255   int nread;
256
257   while ( (nread = pth_read (parm->fd, buffer, sizeof buffer)) )
258     {
259       if (nread < 0)
260         {
261           if (errno == EINTR)
262             continue;
263           *parm->err_addr = gpg_error_from_syserror ();
264           break;  /* Read error.  */
265         }
266       
267       put_membuf (parm->mb, buffer, nread);
268     }
269
270   if (close (parm->fd))
271     log_error ("closing reader fd %d failed: %s\n", parm->fd, strerror (errno));
272   xfree (parm);
273   return NULL;
274 }
275
276
277 /* Fire up a thread to receive data from the file descriptor FD.  On
278    success the thread receives the ownership over FD.  The thread ID
279    is stored at R_TID.  After the thread has finished an error from
280    the thread will be stored at ERR_ADDR.  */
281 static gpg_error_t
282 start_reader (int fd, membuf_t *mb, pth_t *r_tid, gpg_error_t *err_addr)
283 {
284   gpg_error_t err;
285   struct reader_thread_parms *parm;
286   pth_attr_t tattr;
287   pth_t tid;
288
289   *r_tid = NULL;
290   *err_addr = 0;
291
292   parm = xtrymalloc (sizeof *parm);
293   if (!parm)
294     return gpg_error_from_syserror ();
295   parm->fd = fd;
296   parm->mb = mb;
297   parm->err_addr = err_addr;
298
299   tattr = pth_attr_new ();
300   pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1);
301   pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024);
302   pth_attr_set (tattr, PTH_ATTR_NAME, "fd-reader");
303
304   tid = pth_spawn (tattr, reader_thread, parm);
305   if (!tid)
306     {
307       err = gpg_error_from_syserror ();
308       log_error ("error spawning reader thread: %s\n", gpg_strerror (err));
309     }
310   else
311     {
312       err = 0;
313       *r_tid = tid;
314     }
315   pth_attr_destroy (tattr);
316
317   return err;
318 }
319
320
321
322 \f
323 /* Call GPG to encrypt a block of data. 
324
325
326  */
327 gpg_error_t
328 gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen,
329                   void **r_ciph, size_t *r_ciphlen)
330 {
331   gpg_error_t err;
332   assuan_context_t ctx;
333   int outbound_fds[2] = { -1, -1 };
334   int inbound_fds[2]  = { -1, -1 };
335   pth_t writer_tid = NULL;
336   pth_t reader_tid = NULL;
337   gpg_error_t writer_err, reader_err;
338   membuf_t reader_mb;
339
340   *r_ciph = NULL;
341   *r_ciphlen = 0;
342
343   /* Init the memory buffer to receive the encrypted stuff.  */
344   init_membuf (&reader_mb, 4096);
345
346   /* Create two pipes.  */
347   err = gnupg_create_outbound_pipe (outbound_fds);
348   if (!err)
349     err = gnupg_create_inbound_pipe (inbound_fds);
350   if (err)
351     {
352       log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
353       goto leave;
354     }
355
356   /* Start GPG and send the INPUT and OUTPUT commands.  */
357   err = start_gpg (ctrl, outbound_fds[0], inbound_fds[1], &ctx);
358   if (err)
359     goto leave;
360   close (outbound_fds[0]); outbound_fds[0] = -1;
361   close (inbound_fds[1]); inbound_fds[1] = -1;
362   
363   /* Start a writer thread to feed the INPUT command of the server.  */
364   err = start_writer (outbound_fds[1], plain, plainlen, 
365                       &writer_tid, &writer_err);
366   if (err)
367     return err;
368   outbound_fds[1] = -1;  /* The thread owns the FD now.  */
369
370   /* Start a reader thread to eat from the OUTPUT command of the
371      server.  */
372   err = start_reader (inbound_fds[0], &reader_mb, 
373                       &reader_tid, &reader_err);
374   if (err)
375     return err;
376   outbound_fds[0] = -1;  /* The thread owns the FD now.  */
377
378   /* Run the encryption.  */
379   err = assuan_transact (ctx, "RECIPIENT alpha@example.net",
380                          NULL, NULL, NULL, NULL, NULL, NULL);
381   if (err)
382     {
383       log_error ("the engine's RECIPIENT command failed: %s <%s>\n",
384                  gpg_strerror (err), gpg_strsource (err));
385       goto leave;
386     }
387
388   err = assuan_transact (ctx, "ENCRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
389   if (err)
390     {
391       log_error ("the engine's ENCRYPT command failed: %s <%s>\n",
392                  gpg_strerror (err), gpg_strsource (err));
393       goto leave;
394     }
395
396   /* Wait for reader and return the data.  */
397   if (!pth_join (reader_tid, NULL))
398     {
399       err = gpg_error_from_syserror ();
400       log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
401       goto leave;
402     }
403   reader_tid = NULL;
404   if (reader_err)
405     {
406       err = reader_err;
407       log_error ("read error in reader thread: %s\n", gpg_strerror (err));
408       goto leave;
409     }
410
411   /* Wait for the writer to catch  a writer error.  */
412   if (!pth_join (writer_tid, NULL))
413     {
414       err = gpg_error_from_syserror ();
415       log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
416       goto leave;
417     }
418   writer_tid = NULL;
419   if (writer_err)
420     {
421       err = writer_err;
422       log_error ("write error in writer thread: %s\n", gpg_strerror (err));
423       goto leave;
424     }
425
426   /* Return the data.  */
427   *r_ciph = get_membuf (&reader_mb, r_ciphlen);
428   if (!*r_ciph)
429     {
430       err = gpg_error_from_syserror ();
431       log_error ("error while storing the data in the reader thread: %s\n",
432                  gpg_strerror (err));
433       goto leave;
434     }
435
436  leave:
437   if (reader_tid)
438     {
439       pth_cancel (reader_tid);
440       pth_join (reader_tid, NULL);
441     }
442   if (writer_tid)
443     {
444       pth_cancel (writer_tid);
445       pth_join (writer_tid, NULL);
446     }
447   if (outbound_fds[0] != -1)
448     close (outbound_fds[0]);
449   if (outbound_fds[1] != -1)
450     close (outbound_fds[1]);
451   if (inbound_fds[0] != -1)
452     close (inbound_fds[0]);
453   if (inbound_fds[1] != -1)
454     close (inbound_fds[1]);
455   release_gpg (ctx);
456   xfree (get_membuf (&reader_mb, NULL));
457   return err;
458 }
459
460
461 \f
462 /* Call GPG to decrypt a block of data. 
463
464
465  */
466 gpg_error_t
467 gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen,
468                   void **r_plain, size_t *r_plainlen)
469 {
470   gpg_error_t err;
471   assuan_context_t ctx;
472   int outbound_fds[2] = { -1, -1 };
473   int inbound_fds[2]  = { -1, -1 };
474   pth_t writer_tid = NULL;
475   pth_t reader_tid = NULL;
476   gpg_error_t writer_err, reader_err;
477   membuf_t reader_mb;
478
479   *r_plain = NULL;
480   *r_plainlen = 0;
481
482   /* Init the memory buffer to receive the encrypted stuff.  */
483   init_membuf_secure (&reader_mb, 1024);
484
485   /* Create two pipes.  */
486   err = gnupg_create_outbound_pipe (outbound_fds);
487   if (!err)
488     err = gnupg_create_inbound_pipe (inbound_fds);
489   if (err)
490     {
491       log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
492       goto leave;
493     }
494
495   /* Start GPG and send the INPUT and OUTPUT commands.  */
496   err = start_gpg (ctrl, outbound_fds[0], inbound_fds[1], &ctx);
497   if (err)
498     goto leave;
499   close (outbound_fds[0]); outbound_fds[0] = -1;
500   close (inbound_fds[1]); inbound_fds[1] = -1;
501   
502   /* Start a writer thread to feed the INPUT command of the server.  */
503   err = start_writer (outbound_fds[1], ciph, ciphlen, 
504                       &writer_tid, &writer_err);
505   if (err)
506     return err;
507   outbound_fds[1] = -1;  /* The thread owns the FD now.  */
508
509   /* Start a reader thread to eat from the OUTPUT command of the
510      server.  */
511   err = start_reader (inbound_fds[0], &reader_mb, 
512                       &reader_tid, &reader_err);
513   if (err)
514     return err;
515   outbound_fds[0] = -1;  /* The thread owns the FD now.  */
516
517   /* Run the decryption.  */
518   err = assuan_transact (ctx, "DECRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
519   if (err)
520     {
521       log_error ("the engine's DECRYPT command failed: %s <%s>\n",
522                  gpg_strerror (err), gpg_strsource (err));
523       goto leave;
524     }
525
526   /* Wait for reader and return the data.  */
527   if (!pth_join (reader_tid, NULL))
528     {
529       err = gpg_error_from_syserror ();
530       log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
531       goto leave;
532     }
533   reader_tid = NULL;
534   if (reader_err)
535     {
536       err = reader_err;
537       log_error ("read error in reader thread: %s\n", gpg_strerror (err));
538       goto leave;
539     }
540
541   /* Wait for the writer to catch a writer error.  */
542   if (!pth_join (writer_tid, NULL))
543     {
544       err = gpg_error_from_syserror ();
545       log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
546       goto leave;
547     }
548   writer_tid = NULL;
549   if (writer_err)
550     {
551       err = writer_err;
552       log_error ("write error in writer thread: %s\n", gpg_strerror (err));
553       goto leave;
554     }
555
556   /* Return the data.  */
557   *r_plain = get_membuf (&reader_mb, r_plainlen);
558   if (!*r_plain)
559     {
560       err = gpg_error_from_syserror ();
561       log_error ("error while storing the data in the reader thread: %s\n",
562                  gpg_strerror (err));
563       goto leave;
564     }
565
566  leave:
567   if (reader_tid)
568     {
569       pth_cancel (reader_tid);
570       pth_join (reader_tid, NULL);
571     }
572   if (writer_tid)
573     {
574       pth_cancel (writer_tid);
575       pth_join (writer_tid, NULL);
576     }
577   if (outbound_fds[0] != -1)
578     close (outbound_fds[0]);
579   if (outbound_fds[1] != -1)
580     close (outbound_fds[1]);
581   if (inbound_fds[0] != -1)
582     close (inbound_fds[0]);
583   if (inbound_fds[1] != -1)
584     close (inbound_fds[1]);
585   release_gpg (ctx);
586   xfree (get_membuf (&reader_mb, NULL));
587   return err;
588 }
589
590