Imported Upstream version 2.1.0
[platform/upstream/gpg2.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 <npth.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[10];
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++] = "--trust-model";
90   argv[i++] = "always";
91   argv[i++] = NULL;
92
93   i = 0;
94   if (log_get_fd () != -1)
95     no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
96   no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
97   if (input_fd != -1)
98     no_close_list[i++] = assuan_fd_from_posix_fd (input_fd);
99   if (output_fd != -1)
100     no_close_list[i++] = assuan_fd_from_posix_fd (output_fd);
101   no_close_list[i] = -1;
102
103   /* Connect to GPG and perform initial handshaking.  */
104   err = assuan_pipe_connect (ctx, opt.gpg_program, argv, no_close_list,
105                              NULL, NULL, 0);
106   if (err)
107     {
108       assuan_release (ctx);
109       log_error ("can't connect to GPG: %s\n", gpg_strerror (err));
110       return gpg_error (GPG_ERR_NO_ENGINE);
111     }
112
113   if (input_fd != -1)
114     {
115       snprintf (line, sizeof line, "INPUT FD=%d", input_fd);
116       err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
117       if (err)
118         {
119           assuan_release (ctx);
120           log_error ("error sending INPUT command: %s\n", gpg_strerror (err));
121           return err;
122         }
123     }
124
125   if (output_fd != -1)
126     {
127       snprintf (line, sizeof line, "OUTPUT FD=%d", output_fd);
128       err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
129       if (err)
130         {
131           assuan_release (ctx);
132           log_error ("error sending OUTPUT command: %s\n", gpg_strerror (err));
133           return err;
134         }
135     }
136
137   *r_ctx = ctx;
138
139   if (DBG_ASSUAN)
140     log_debug ("connection to GPG established\n");
141   return 0;
142 }
143
144
145 /* Release the assuan context created by start_gpg.  */
146 static void
147 release_gpg (assuan_context_t ctx)
148 {
149   assuan_release (ctx);
150 }
151
152
153 \f
154 /* The data passed to the writer_thread.  */
155 struct writer_thread_parms
156 {
157   int fd;
158   const void *data;
159   size_t datalen;
160   gpg_error_t *err_addr;
161 };
162
163
164 /* The thread started by start_writer.  */
165 static void *
166 writer_thread_main (void *arg)
167 {
168   struct writer_thread_parms *parm = arg;
169   const char *buffer = parm->data;
170   size_t length = parm->datalen;
171
172   while (length)
173     {
174       ssize_t nwritten;
175
176       nwritten = npth_write (parm->fd, buffer, length < 4096? length:4096);
177       if (nwritten < 0)
178         {
179           if (errno == EINTR)
180             continue;
181           *parm->err_addr = gpg_error_from_syserror ();
182           break; /* Write error.  */
183         }
184       length -= nwritten;
185       buffer += nwritten;
186     }
187
188   if (close (parm->fd))
189     log_error ("closing writer fd %d failed: %s\n", parm->fd, strerror (errno));
190   xfree (parm);
191   return NULL;
192 }
193
194
195 /* Fire up a thread to send (DATA,DATALEN) to the file descriptor FD.
196    On success the thread receives the ownership over FD.  The thread
197    ID is stored at R_TID.  WRITER_ERR is the address of an gpg_error_t
198    variable to receive a possible write error after the thread has
199    finished.  */
200 static gpg_error_t
201 start_writer (int fd, const void *data, size_t datalen,
202               npth_t *r_thread, gpg_error_t *err_addr)
203 {
204   gpg_error_t err;
205   struct writer_thread_parms *parm;
206   npth_attr_t tattr;
207   npth_t thread;
208   int ret;
209
210   memset (r_thread, '\0', sizeof (*r_thread));
211   *err_addr = 0;
212
213   parm = xtrymalloc (sizeof *parm);
214   if (!parm)
215     return gpg_error_from_syserror ();
216   parm->fd = fd;
217   parm->data = data;
218   parm->datalen = datalen;
219   parm->err_addr = err_addr;
220
221   npth_attr_init (&tattr);
222   npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
223
224   ret = npth_create (&thread, &tattr, writer_thread_main, parm);
225   if (ret)
226     {
227       err = gpg_error_from_errno (ret);
228       log_error ("error spawning writer thread: %s\n", gpg_strerror (err));
229     }
230   else
231     {
232       npth_setname_np (thread, "fd-writer");
233       err = 0;
234       *r_thread = thread;
235     }
236   npth_attr_destroy (&tattr);
237
238   return err;
239 }
240
241
242 \f
243 /* The data passed to the reader_thread.  */
244 struct reader_thread_parms
245 {
246   int fd;
247   membuf_t *mb;
248   gpg_error_t *err_addr;
249 };
250
251
252 /* The thread started by start_reader.  */
253 static void *
254 reader_thread_main (void *arg)
255 {
256   struct reader_thread_parms *parm = arg;
257   char buffer[4096];
258   int nread;
259
260   while ( (nread = npth_read (parm->fd, buffer, sizeof buffer)) )
261     {
262       if (nread < 0)
263         {
264           if (errno == EINTR)
265             continue;
266           *parm->err_addr = gpg_error_from_syserror ();
267           break;  /* Read error.  */
268         }
269
270       put_membuf (parm->mb, buffer, nread);
271     }
272
273   if (close (parm->fd))
274     log_error ("closing reader fd %d failed: %s\n", parm->fd, strerror (errno));
275   xfree (parm);
276   return NULL;
277 }
278
279
280 /* Fire up a thread to receive data from the file descriptor FD.  On
281    success the thread receives the ownership over FD.  The thread ID
282    is stored at R_TID.  After the thread has finished an error from
283    the thread will be stored at ERR_ADDR.  */
284 static gpg_error_t
285 start_reader (int fd, membuf_t *mb, npth_t *r_thread, gpg_error_t *err_addr)
286 {
287   gpg_error_t err;
288   struct reader_thread_parms *parm;
289   npth_attr_t tattr;
290   npth_t thread;
291   int ret;
292
293   memset (r_thread, '\0', sizeof (*r_thread));
294   *err_addr = 0;
295
296   parm = xtrymalloc (sizeof *parm);
297   if (!parm)
298     return gpg_error_from_syserror ();
299   parm->fd = fd;
300   parm->mb = mb;
301   parm->err_addr = err_addr;
302
303   npth_attr_init (&tattr);
304   npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
305
306   ret = npth_create (&thread, &tattr, reader_thread_main, parm);
307   if (ret)
308     {
309       err = gpg_error_from_errno (ret);
310       log_error ("error spawning reader thread: %s\n", gpg_strerror (err));
311     }
312   else
313     {
314       npth_setname_np (thread, "fd-reader");
315       err = 0;
316       *r_thread = thread;
317     }
318   npth_attr_destroy (&tattr);
319
320   return err;
321 }
322
323
324
325 \f
326 /* Call GPG to encrypt a block of data.
327
328
329  */
330 gpg_error_t
331 gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen,
332                   strlist_t keys, void **r_ciph, size_t *r_ciphlen)
333 {
334   gpg_error_t err;
335   assuan_context_t ctx = NULL;
336   int outbound_fds[2] = { -1, -1 };
337   int inbound_fds[2]  = { -1, -1 };
338   npth_t writer_thread = (npth_t)0;
339   npth_t reader_thread = (npth_t)0;
340   gpg_error_t writer_err, reader_err;
341   membuf_t reader_mb;
342   char line[ASSUAN_LINELENGTH];
343   strlist_t sl;
344   int ret;
345
346   *r_ciph = NULL;
347   *r_ciphlen = 0;
348
349   /* Init the memory buffer to receive the encrypted stuff.  */
350   init_membuf (&reader_mb, 4096);
351
352   /* Create two pipes.  */
353   err = gnupg_create_outbound_pipe (outbound_fds);
354   if (!err)
355     err = gnupg_create_inbound_pipe (inbound_fds);
356   if (err)
357     {
358       log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
359       goto leave;
360     }
361
362   /* Start GPG and send the INPUT and OUTPUT commands.  */
363   err = start_gpg (ctrl, outbound_fds[0], inbound_fds[1], &ctx);
364   if (err)
365     goto leave;
366   close (outbound_fds[0]); outbound_fds[0] = -1;
367   close (inbound_fds[1]); inbound_fds[1] = -1;
368
369   /* Start a writer thread to feed the INPUT command of the server.  */
370   err = start_writer (outbound_fds[1], plain, plainlen,
371                       &writer_thread, &writer_err);
372   if (err)
373     return err;
374   outbound_fds[1] = -1;  /* The thread owns the FD now.  */
375
376   /* Start a reader thread to eat from the OUTPUT command of the
377      server.  */
378   err = start_reader (inbound_fds[0], &reader_mb,
379                       &reader_thread, &reader_err);
380   if (err)
381     return err;
382   outbound_fds[0] = -1;  /* The thread owns the FD now.  */
383
384   /* Run the encryption.  */
385   for (sl = keys; sl; sl = sl->next)
386     {
387       snprintf (line, sizeof line, "RECIPIENT -- %s", sl->d);
388       err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
389       if (err)
390         {
391           log_error ("the engine's RECIPIENT command failed: %s <%s>\n",
392                  gpg_strerror (err), gpg_strsource (err));
393           goto leave;
394         }
395     }
396
397   err = assuan_transact (ctx, "ENCRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
398   if (err)
399     {
400       log_error ("the engine's ENCRYPT command failed: %s <%s>\n",
401                  gpg_strerror (err), gpg_strsource (err));
402       goto leave;
403     }
404
405   /* Wait for reader and return the data.  */
406   ret = npth_join (reader_thread, NULL);
407   if (ret)
408     {
409       err = gpg_error_from_errno (ret);
410       log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
411       goto leave;
412     }
413   /* FIXME: Not really valid, as npth_t is an opaque type.  */
414   memset (&reader_thread, '\0', sizeof (reader_thread));
415   if (reader_err)
416     {
417       err = reader_err;
418       log_error ("read error in reader thread: %s\n", gpg_strerror (err));
419       goto leave;
420     }
421
422   /* Wait for the writer to catch  a writer error.  */
423   ret = npth_join (writer_thread, NULL);
424   if (ret)
425     {
426       err = gpg_error_from_errno (ret);
427       log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
428       goto leave;
429     }
430   memset (&writer_thread, '\0', sizeof (writer_thread));
431   if (writer_err)
432     {
433       err = writer_err;
434       log_error ("write error in writer thread: %s\n", gpg_strerror (err));
435       goto leave;
436     }
437
438   /* Return the data.  */
439   *r_ciph = get_membuf (&reader_mb, r_ciphlen);
440   if (!*r_ciph)
441     {
442       err = gpg_error_from_syserror ();
443       log_error ("error while storing the data in the reader thread: %s\n",
444                  gpg_strerror (err));
445       goto leave;
446     }
447
448  leave:
449   /* FIXME: Not valid, as npth_t is an opaque type.  */
450   if (reader_thread)
451     npth_detach (reader_thread);
452   if (writer_thread)
453     npth_detach (writer_thread);
454   if (outbound_fds[0] != -1)
455     close (outbound_fds[0]);
456   if (outbound_fds[1] != -1)
457     close (outbound_fds[1]);
458   if (inbound_fds[0] != -1)
459     close (inbound_fds[0]);
460   if (inbound_fds[1] != -1)
461     close (inbound_fds[1]);
462   release_gpg (ctx);
463   xfree (get_membuf (&reader_mb, NULL));
464   return err;
465 }
466
467
468 \f
469 /* Call GPG to decrypt a block of data.
470
471
472  */
473 gpg_error_t
474 gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen,
475                   void **r_plain, size_t *r_plainlen)
476 {
477   gpg_error_t err;
478   assuan_context_t ctx = NULL;
479   int outbound_fds[2] = { -1, -1 };
480   int inbound_fds[2]  = { -1, -1 };
481   npth_t writer_thread = (npth_t)0;
482   npth_t reader_thread = (npth_t)0;
483   gpg_error_t writer_err, reader_err;
484   membuf_t reader_mb;
485   int ret;
486
487   *r_plain = NULL;
488   *r_plainlen = 0;
489
490   /* Init the memory buffer to receive the encrypted stuff.  */
491   init_membuf_secure (&reader_mb, 1024);
492
493   /* Create two pipes.  */
494   err = gnupg_create_outbound_pipe (outbound_fds);
495   if (!err)
496     err = gnupg_create_inbound_pipe (inbound_fds);
497   if (err)
498     {
499       log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
500       goto leave;
501     }
502
503   /* Start GPG and send the INPUT and OUTPUT commands.  */
504   err = start_gpg (ctrl, outbound_fds[0], inbound_fds[1], &ctx);
505   if (err)
506     goto leave;
507   close (outbound_fds[0]); outbound_fds[0] = -1;
508   close (inbound_fds[1]); inbound_fds[1] = -1;
509
510   /* Start a writer thread to feed the INPUT command of the server.  */
511   err = start_writer (outbound_fds[1], ciph, ciphlen,
512                       &writer_thread, &writer_err);
513   if (err)
514     return err;
515   outbound_fds[1] = -1;  /* The thread owns the FD now.  */
516
517   /* Start a reader thread to eat from the OUTPUT command of the
518      server.  */
519   err = start_reader (inbound_fds[0], &reader_mb,
520                       &reader_thread, &reader_err);
521   if (err)
522     return err;
523   outbound_fds[0] = -1;  /* The thread owns the FD now.  */
524
525   /* Run the decryption.  */
526   err = assuan_transact (ctx, "DECRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
527   if (err)
528     {
529       log_error ("the engine's DECRYPT command failed: %s <%s>\n",
530                  gpg_strerror (err), gpg_strsource (err));
531       goto leave;
532     }
533
534   /* Wait for reader and return the data.  */
535   ret = npth_join (reader_thread, NULL);
536   if (ret)
537     {
538       err = gpg_error_from_errno (ret);
539       log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
540       goto leave;
541     }
542   memset (&reader_thread, '\0', sizeof (reader_thread));
543   if (reader_err)
544     {
545       err = reader_err;
546       log_error ("read error in reader thread: %s\n", gpg_strerror (err));
547       goto leave;
548     }
549
550   /* Wait for the writer to catch a writer error.  */
551   ret = npth_join (writer_thread, NULL);
552   if (ret)
553     {
554       err = gpg_error_from_errno (ret);
555       log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
556       goto leave;
557     }
558   memset (&writer_thread, '\0', sizeof (writer_thread));
559   if (writer_err)
560     {
561       err = writer_err;
562       log_error ("write error in writer thread: %s\n", gpg_strerror (err));
563       goto leave;
564     }
565
566   /* Return the data.  */
567   *r_plain = get_membuf (&reader_mb, r_plainlen);
568   if (!*r_plain)
569     {
570       err = gpg_error_from_syserror ();
571       log_error ("error while storing the data in the reader thread: %s\n",
572                  gpg_strerror (err));
573       goto leave;
574     }
575
576  leave:
577   if (reader_thread)
578     npth_detach (reader_thread);
579   if (writer_thread)
580     npth_detach (writer_thread);
581   if (outbound_fds[0] != -1)
582     close (outbound_fds[0]);
583   if (outbound_fds[1] != -1)
584     close (outbound_fds[1]);
585   if (inbound_fds[0] != -1)
586     close (inbound_fds[0]);
587   if (inbound_fds[1] != -1)
588     close (inbound_fds[1]);
589   release_gpg (ctx);
590   xfree (get_membuf (&reader_mb, NULL));
591   return err;
592 }