gpg: Make the double space in the middle of a fingerprint optional.
[gnupg.git] / common / asshelp.c
1 /* asshelp.c - Helper functions for Assuan
2  * Copyright (C) 2002, 2004, 2007, 2009, 2010 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 <unistd.h>
25 #include <errno.h>
26 #ifdef HAVE_LOCALE_H
27 #include <locale.h>
28 #endif
29
30 #define JNLIB_NEED_LOG_LOGV
31 #include "i18n.h"
32 #include "util.h"
33 #include "exechelp.h"
34 #include "sysutils.h"
35 #include "status.h"
36 #include "asshelp.h"
37
38 /* The type we use for lock_agent_spawning.  */
39 #ifdef HAVE_W32_SYSTEM
40 # define lock_spawn_t HANDLE
41 #else
42 # define lock_spawn_t dotlock_t
43 #endif
44
45 /* The time we wait until the agent or the dirmngr are ready for
46    operation after we started them before giving up.  */
47 #ifdef HAVE_W32CE_SYSTEM
48 # define SECS_TO_WAIT_FOR_AGENT 30
49 # define SECS_TO_WAIT_FOR_DIRMNGR 30
50 #else
51 # define SECS_TO_WAIT_FOR_AGENT 5
52 # define SECS_TO_WAIT_FOR_DIRMNGR 5
53 #endif
54
55 /* A bitfield that specifies the assuan categories to log.  This is
56    identical to the default log handler of libassuan.  We need to do
57    it ourselves because we use a custom log handler and want to use
58    the same assuan variables to select the categories to log. */
59 static int log_cats;
60 #define TEST_LOG_CAT(x) (!! (log_cats & (1 << (x - 1))))
61
62
63 static int
64 my_libassuan_log_handler (assuan_context_t ctx, void *hook,
65                           unsigned int cat, const char *msg)
66 {
67   unsigned int dbgval;
68
69   (void)ctx;
70
71   if (! TEST_LOG_CAT (cat))
72     return 0;
73
74   dbgval = hook? *(unsigned int*)hook : 0;
75   if (!(dbgval & 1024))
76     return 0; /* Assuan debugging is not enabled.  */
77
78   if (msg)
79     log_string (JNLIB_LOG_DEBUG, msg);
80
81   return 1;
82 }
83
84
85 /* Setup libassuan to use our own logging functions.  Should be used
86    early at startup.  */
87 void
88 setup_libassuan_logging (unsigned int *debug_var_address)
89 {
90   char *flagstr;
91
92   flagstr = getenv ("ASSUAN_DEBUG");
93   if (flagstr)
94     log_cats = atoi (flagstr);
95   else /* Default to log the control channel.  */
96     log_cats = (1 << (ASSUAN_LOG_CONTROL - 1));
97   assuan_set_log_cb (my_libassuan_log_handler, debug_var_address);
98 }
99
100 /* Change the Libassuan log categories to those given by NEWCATS.
101    NEWCATS is 0 the default category of ASSUAN_LOG_CONTROL is
102    selected.  Note, that setup_libassuan_logging overrides the values
103    given here.  */
104 void
105 set_libassuan_log_cats (unsigned int newcats)
106 {
107   if (newcats)
108     log_cats = newcats;
109   else /* Default to log the control channel.  */
110     log_cats = (1 << (ASSUAN_LOG_CONTROL - 1));
111 }
112
113
114
115 static gpg_error_t
116 send_one_option (assuan_context_t ctx, gpg_err_source_t errsource,
117                  const char *name, const char *value, int use_putenv)
118 {
119   gpg_error_t err;
120   char *optstr;
121
122   (void)errsource;
123
124   if (!value || !*value)
125     err = 0;  /* Avoid sending empty strings.  */
126   else if (asprintf (&optstr, "OPTION %s%s=%s",
127                      use_putenv? "putenv=":"", name, value) < 0)
128     err = gpg_error_from_syserror ();
129   else
130     {
131       err = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL);
132       xfree (optstr);
133     }
134
135   return err;
136 }
137
138
139 /* Send the assuan commands pertaining to the pinentry environment.  The
140    OPT_* arguments are optional and may be used to override the
141    defaults taken from the current locale. */
142 gpg_error_t
143 send_pinentry_environment (assuan_context_t ctx,
144                            gpg_err_source_t errsource,
145                            const char *opt_lc_ctype,
146                            const char *opt_lc_messages,
147                            session_env_t session_env)
148
149 {
150   gpg_error_t err = 0;
151 #if defined(HAVE_SETLOCALE)
152   char *old_lc = NULL;
153 #endif
154   char *dft_lc = NULL;
155   const char *dft_ttyname;
156   int iterator;
157   const char *name, *assname, *value;
158   int is_default;
159
160   iterator = 0;
161   while ((name = session_env_list_stdenvnames (&iterator, &assname)))
162     {
163       value = session_env_getenv_or_default (session_env, name, NULL);
164       if (!value)
165         continue;
166
167       if (assname)
168         err = send_one_option (ctx, errsource, assname, value, 0);
169       else
170         {
171           err = send_one_option (ctx, errsource, name, value, 1);
172           if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
173             err = 0;  /* Server too old; can't pass the new envvars.  */
174         }
175       if (err)
176         return err;
177     }
178
179
180   dft_ttyname = session_env_getenv_or_default (session_env, "GPG_TTY",
181                                                &is_default);
182   if (dft_ttyname && !is_default)
183     dft_ttyname = NULL;  /* We need the default value.  */
184
185   /* Send the value for LC_CTYPE.  */
186 #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
187   old_lc = setlocale (LC_CTYPE, NULL);
188   if (old_lc)
189     {
190       old_lc = xtrystrdup (old_lc);
191       if (!old_lc)
192         return gpg_error_from_syserror ();
193     }
194   dft_lc = setlocale (LC_CTYPE, "");
195 #endif
196   if (opt_lc_ctype || (dft_ttyname && dft_lc))
197     {
198       err = send_one_option (ctx, errsource, "lc-ctype",
199                              opt_lc_ctype ? opt_lc_ctype : dft_lc, 0);
200     }
201 #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
202   if (old_lc)
203     {
204       setlocale (LC_CTYPE, old_lc);
205       xfree (old_lc);
206     }
207 #endif
208   if (err)
209     return err;
210
211   /* Send the value for LC_MESSAGES.  */
212 #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
213   old_lc = setlocale (LC_MESSAGES, NULL);
214   if (old_lc)
215     {
216       old_lc = xtrystrdup (old_lc);
217       if (!old_lc)
218         return gpg_error_from_syserror ();
219     }
220   dft_lc = setlocale (LC_MESSAGES, "");
221 #endif
222   if (opt_lc_messages || (dft_ttyname && dft_lc))
223     {
224       err = send_one_option (ctx, errsource, "lc-messages",
225                              opt_lc_messages ? opt_lc_messages : dft_lc, 0);
226     }
227 #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
228   if (old_lc)
229     {
230       setlocale (LC_MESSAGES, old_lc);
231       xfree (old_lc);
232     }
233 #endif
234   if (err)
235     return err;
236
237   return 0;
238 }
239
240
241 /* Lock a spawning process.  The caller needs to provide the address
242    of a variable to store the lock information and the name or the
243    process.  */
244 static gpg_error_t
245 lock_spawning (lock_spawn_t *lock, const char *homedir, const char *name,
246                int verbose)
247 {
248 #ifdef HAVE_W32_SYSTEM
249   int waitrc;
250   int timeout = (!strcmp (name, "agent")
251                  ? SECS_TO_WAIT_FOR_AGENT
252                  : SECS_TO_WAIT_FOR_DIRMNGR);
253
254   (void)homedir; /* Not required. */
255
256   *lock = CreateMutexW
257     (NULL, FALSE,
258      !strcmp (name, "agent")?   L"GnuPG_spawn_agent_sentinel":
259      !strcmp (name, "dirmngr")? L"GnuPG_spawn_dirmngr_sentinel":
260      /*                    */   L"GnuPG_spawn_unknown_sentinel");
261   if (!*lock)
262     {
263       log_error ("failed to create the spawn_%s mutex: %s\n",
264                  name, w32_strerror (-1));
265       return gpg_error (GPG_ERR_GENERAL);
266     }
267
268  retry:
269   waitrc = WaitForSingleObject (*lock, 1000);
270   if (waitrc == WAIT_OBJECT_0)
271     return 0;
272
273   if (waitrc == WAIT_TIMEOUT && timeout)
274     {
275       timeout--;
276       if (verbose)
277         log_info ("another process is trying to start the %s ... (%ds)\n",
278                   name, timeout);
279       goto retry;
280     }
281   if (waitrc == WAIT_TIMEOUT)
282     log_info ("error waiting for the spawn_%s mutex: timeout\n", name);
283   else
284     log_info ("error waiting for the spawn_%s mutex: (code=%d) %s\n",
285               name, waitrc, w32_strerror (-1));
286   return gpg_error (GPG_ERR_GENERAL);
287 #else /*!HAVE_W32_SYSTEM*/
288   char *fname;
289
290   (void)verbose;
291
292   *lock = NULL;
293
294   fname = make_filename
295     (homedir,
296      !strcmp (name, "agent")?   "gnupg_spawn_agent_sentinel":
297      !strcmp (name, "dirmngr")? "gnupg_spawn_dirmngr_sentinel":
298      /*                    */   "gnupg_spawn_unknown_sentinel",
299      NULL);
300   if (!fname)
301     return gpg_error_from_syserror ();
302
303   *lock = dotlock_create (fname, 0);
304   xfree (fname);
305   if (!*lock)
306     return gpg_error_from_syserror ();
307
308   /* FIXME: We should use a timeout of 5000 here - however
309      make_dotlock does not yet support values other than -1 and 0.  */
310   if (dotlock_take (*lock, -1))
311     return gpg_error_from_syserror ();
312
313   return 0;
314 #endif /*!HAVE_W32_SYSTEM*/
315 }
316
317
318 /* Unlock the spawning process.  */
319 static void
320 unlock_spawning (lock_spawn_t *lock, const char *name)
321 {
322   if (*lock)
323     {
324 #ifdef HAVE_W32_SYSTEM
325       if (!ReleaseMutex (*lock))
326         log_error ("failed to release the spawn_%s mutex: %s\n",
327                    name, w32_strerror (-1));
328       CloseHandle (*lock);
329 #else /*!HAVE_W32_SYSTEM*/
330       (void)name;
331       dotlock_destroy (*lock);
332 #endif /*!HAVE_W32_SYSTEM*/
333       *lock = NULL;
334     }
335 }
336
337 /* Try to connect to the agent via socket or fork it off and work by
338    pipes.  Handle the server's initial greeting.  Returns a new assuan
339    context at R_CTX or an error code. */
340 gpg_error_t
341 start_new_gpg_agent (assuan_context_t *r_ctx,
342                      gpg_err_source_t errsource,
343                      const char *homedir,
344                      const char *agent_program,
345                      const char *opt_lc_ctype,
346                      const char *opt_lc_messages,
347                      session_env_t session_env,
348                      int verbose, int debug,
349                      gpg_error_t (*status_cb)(ctrl_t, int, ...),
350                      ctrl_t status_cb_arg)
351 {
352   /* If we ever failed to connect via a socket we will force the use
353      of the pipe based server for the lifetime of the process.  */
354   static int force_pipe_server = 0;
355
356   gpg_error_t err = 0;
357   char *infostr, *p;
358   assuan_context_t ctx;
359   int did_success_msg = 0;
360
361   *r_ctx = NULL;
362
363   err = assuan_new (&ctx);
364   if (err)
365     {
366       log_error ("error allocating assuan context: %s\n", gpg_strerror (err));
367       return err;
368     }
369
370  restart:
371   infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO");
372   if (!infostr || !*infostr)
373     {
374       char *sockname;
375       const char *argv[3];
376       pid_t pid;
377       int excode;
378
379       /* First check whether we can connect at the standard
380          socket.  */
381       sockname = make_filename (homedir, "S.gpg-agent", NULL);
382       err = assuan_socket_connect (ctx, sockname, 0, 0);
383
384       if (err)
385         {
386           /* With no success start a new server.  */
387           if (!agent_program || !*agent_program)
388             agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
389
390           if (verbose)
391             log_info (_("no running gpg-agent - starting `%s'\n"),
392                       agent_program);
393
394           if (status_cb)
395             status_cb (status_cb_arg, STATUS_PROGRESS,
396                        "starting_agent ? 0 0", NULL);
397
398           if (fflush (NULL))
399             {
400               gpg_error_t tmperr = gpg_err_make (errsource,
401                                                  gpg_err_code_from_syserror ());
402               log_error ("error flushing pending output: %s\n",
403                          strerror (errno));
404               xfree (sockname);
405               assuan_release (ctx);
406               return tmperr;
407             }
408
409           argv[0] = "--use-standard-socket-p";
410           argv[1] = NULL;
411           err = gnupg_spawn_process_fd (agent_program, argv, -1, -1, -1, &pid);
412           if (err)
413             log_debug ("starting `%s' for testing failed: %s\n",
414                        agent_program, gpg_strerror (err));
415           else if ((err = gnupg_wait_process (agent_program, pid, 1, &excode)))
416             {
417               if (excode == -1)
418                 log_debug ("running `%s' for testing failed (wait): %s\n",
419                            agent_program, gpg_strerror (err));
420             }
421           gnupg_release_process (pid);
422
423           if (!err && !excode)
424             {
425               /* If the agent has been configured for use with a
426                  standard socket, an environment variable is not
427                  required and thus we we can savely start the agent
428                  here.  */
429               lock_spawn_t lock;
430
431               argv[0] = "--daemon";
432               argv[1] = "--use-standard-socket";
433               argv[2] = NULL;
434
435               if (!(err = lock_spawning (&lock, homedir, "agent", verbose))
436                   && assuan_socket_connect (ctx, sockname, 0, 0))
437                 {
438                   err = gnupg_spawn_process_detached (agent_program, argv,NULL);
439                   if (err)
440                     log_error ("failed to start agent `%s': %s\n",
441                                agent_program, gpg_strerror (err));
442                   else
443                     {
444                       int i;
445
446                       for (i=0; i < SECS_TO_WAIT_FOR_AGENT; i++)
447                         {
448                           if (verbose)
449                             log_info (_("waiting for the agent "
450                                         "to come up ... (%ds)\n"),
451                                       SECS_TO_WAIT_FOR_AGENT - i);
452                           gnupg_sleep (1);
453                           err = assuan_socket_connect (ctx, sockname, 0, 0);
454                           if (!err)
455                             {
456                               if (verbose)
457                                 {
458                                   log_info (_("connection to agent "
459                                               "established\n"));
460                                   did_success_msg = 1;
461                                 }
462                               break;
463                             }
464                         }
465                     }
466                 }
467
468               unlock_spawning (&lock, "agent");
469             }
470           else
471             {
472               /* If using the standard socket is not the default we
473                  start the agent as a pipe server which gives us most
474                  of the required features except for passphrase
475                  caching etc.  */
476               const char *pgmname;
477               int no_close_list[3];
478               int i;
479
480               if ( !(pgmname = strrchr (agent_program, '/')))
481                 pgmname = agent_program;
482               else
483                 pgmname++;
484
485               argv[0] = pgmname;
486               argv[1] = "--server";
487               argv[2] = NULL;
488
489               i=0;
490               if (log_get_fd () != -1)
491                 no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
492               no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
493               no_close_list[i] = -1;
494
495               /* Connect to the agent and perform initial handshaking. */
496               err = assuan_pipe_connect (ctx, agent_program, argv,
497                                          no_close_list, NULL, NULL, 0);
498             }
499         }
500       xfree (sockname);
501     }
502   else
503     {
504       int prot;
505       int pid;
506
507       infostr = xstrdup (infostr);
508       if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
509         {
510           log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
511           xfree (infostr);
512           force_pipe_server = 1;
513           goto restart;
514         }
515       *p++ = 0;
516       pid = atoi (p);
517       while (*p && *p != PATHSEP_C)
518         p++;
519       prot = *p? atoi (p+1) : 0;
520       if (prot != 1)
521         {
522           log_error (_("gpg-agent protocol version %d is not supported\n"),
523                      prot);
524           xfree (infostr);
525           force_pipe_server = 1;
526           goto restart;
527         }
528
529       err = assuan_socket_connect (ctx, infostr, pid, 0);
530       xfree (infostr);
531       if (gpg_err_code (err) == GPG_ERR_ASS_CONNECT_FAILED)
532         {
533           log_info (_("can't connect to the agent - trying fall back\n"));
534           force_pipe_server = 1;
535           goto restart;
536         }
537     }
538
539   if (err)
540     {
541       log_error ("can't connect to the agent: %s\n", gpg_strerror (err));
542       assuan_release (ctx);
543       return gpg_err_make (errsource, GPG_ERR_NO_AGENT);
544     }
545
546   if (debug && !did_success_msg)
547     log_debug (_("connection to agent established\n"));
548
549   err = assuan_transact (ctx, "RESET",
550                         NULL, NULL, NULL, NULL, NULL, NULL);
551   if (!err)
552     err = send_pinentry_environment (ctx, errsource,
553                                     opt_lc_ctype, opt_lc_messages,
554                                     session_env);
555   if (err)
556     {
557       assuan_release (ctx);
558       return err;
559     }
560
561   *r_ctx = ctx;
562   return 0;
563 }
564
565
566 /* Try to connect to the dirmngr via a socket.  On platforms
567    supporting it, start it up if needed.  Returns a new assuan context
568    at R_CTX or an error code. */
569 gpg_error_t
570 start_new_dirmngr (assuan_context_t *r_ctx,
571                    gpg_err_source_t errsource,
572                    const char *homedir,
573                    const char *dirmngr_program,
574                    int verbose, int debug,
575                    gpg_error_t (*status_cb)(ctrl_t, int, ...),
576                    ctrl_t status_cb_arg)
577 {
578   gpg_error_t err;
579   assuan_context_t ctx;
580   const char *sockname;
581   int did_success_msg = 0;
582
583   *r_ctx = NULL;
584
585   err = assuan_new (&ctx);
586   if (err)
587     {
588       log_error ("error allocating assuan context: %s\n", gpg_strerror (err));
589       return err;
590     }
591
592   sockname = dirmngr_socket_name ();
593   err = assuan_socket_connect (ctx, sockname, 0, 0);
594 #ifdef USE_DIRMNGR_AUTO_START
595   if (err)
596     {
597       lock_spawn_t lock;
598       const char *argv[2];
599
600       /* With no success try start a new Dirmngr.  On most systems
601          this will fail because the Dirmngr is expected to be a system
602          service.  However on Wince we don't distinguish users and
603          thus we can start it.  A future extension might be to use the
604          userv system to start the Dirmngr as a system service.  */
605       if (!dirmngr_program || !*dirmngr_program)
606         dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR);
607
608       if (verbose)
609         log_info (_("no running Dirmngr - starting `%s'\n"),
610                   dirmngr_program);
611
612       if (status_cb)
613         status_cb (status_cb_arg, STATUS_PROGRESS,
614                    "starting_dirmngr ? 0 0", NULL);
615
616       if (fflush (NULL))
617         {
618           gpg_error_t tmperr = gpg_err_make (errsource,
619                                              gpg_err_code_from_syserror ());
620           log_error ("error flushing pending output: %s\n",
621                      strerror (errno));
622           assuan_release (ctx);
623           return tmperr;
624         }
625
626       argv[0] = "--daemon";
627       argv[1] = NULL;
628
629       if (!(err = lock_spawning (&lock, homedir, "dirmngr", verbose))
630           && assuan_socket_connect (ctx, sockname, 0, 0))
631         {
632           err = gnupg_spawn_process_detached (dirmngr_program, argv,NULL);
633           if (err)
634             log_error ("failed to start the dirmngr `%s': %s\n",
635                        dirmngr_program, gpg_strerror (err));
636           else
637             {
638               int i;
639
640               for (i=0; i < SECS_TO_WAIT_FOR_DIRMNGR; i++)
641                 {
642                   if (verbose)
643                     log_info (_("waiting for the dirmngr "
644                                 "to come up ... (%ds)\n"),
645                               SECS_TO_WAIT_FOR_DIRMNGR - i);
646                   gnupg_sleep (1);
647                   err = assuan_socket_connect (ctx, sockname, 0, 0);
648                   if (!err)
649                     {
650                       if (verbose)
651                         {
652                           log_info (_("connection to the dirmngr"
653                                       " established\n"));
654                           did_success_msg = 1;
655                         }
656                       break;
657                     }
658                 }
659             }
660         }
661
662       unlock_spawning (&lock, "dirmngr");
663     }
664 #else
665   (void)homedir;
666   (void)dirmngr_program;
667   (void)verbose;
668   (void)status_cb;
669   (void)status_cb_arg;
670 #endif /*USE_DIRMNGR_AUTO_START*/
671
672   if (err)
673     {
674       log_error ("connecting dirmngr at `%s' failed: %s\n",
675                  sockname, gpg_strerror (err));
676       assuan_release (ctx);
677       return gpg_err_make (errsource, GPG_ERR_NO_DIRMNGR);
678     }
679
680   if (debug && !did_success_msg)
681     log_debug (_("connection to the dirmngr established\n"));
682
683   *r_ctx = ctx;
684   return 0;
685 }