New debugging optionhs, updates to the manual.
[gnupg.git] / agent / query.c
1 /* query.c - fork of the pinentry to query stuff from the user
2  * Copyright (C) 2001, 2002, 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 2 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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <assert.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #ifdef USE_GNU_PTH
31 # include <pth.h>
32 #endif
33
34 #include "agent.h"
35 #include "i18n.h"
36 #include <assuan.h>
37
38 #ifdef _POSIX_OPEN_MAX
39 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
40 #else
41 #define MAX_OPEN_FDS 20
42 #endif
43
44
45 /* Because access to the pinentry must be serialized (it is and shall
46    be a global mutual dialog) we should better timeout further
47    requests after some time.  2 minutes seem to be a reasonable
48    time. */
49 #define LOCK_TIMEOUT  (1*60)
50
51
52 static assuan_context_t entry_ctx = NULL;
53 #ifdef USE_GNU_PTH
54 static pth_mutex_t entry_lock;
55 #endif
56
57 /* data to be passed to our callbacks */
58 struct entry_parm_s {
59   int lines;
60   size_t size;
61   char *buffer;
62 };
63
64
65
66 \f
67 /* This function must be called once to initialize this module.  This
68    has to be done before a second thread is spawned.  We can't do the
69    static initialization because Pth emulation code might not be able
70    to do a static init; in particualr, it is not possible for W32. */
71 void
72 initialize_module_query (void)
73 {
74 #ifdef USE_GNU_PTH
75   static int initialized;
76
77   if (!initialized)
78     if (pth_mutex_init (&entry_lock))
79       initialized = 1;
80 #endif /*USE_GNU_PTH*/
81 }
82
83
84
85 static void
86 dump_mutex_state (pth_mutex_t *m)
87 {
88   if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
89     log_printf ("not_initialized");
90   else if (!(m->mx_state & PTH_MUTEX_LOCKED))
91     log_printf ("not_locked");
92   else
93     log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
94 }
95
96
97 /* This function may be called to print infromation pertaining to the
98    current state of this module to the log. */
99 void
100 agent_query_dump_state (void)
101 {
102   log_info ("agent_query_dump_state: entry_lock=");
103   dump_mutex_state (&entry_lock);
104   log_printf ("\n");
105   log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld\n",
106             entry_ctx, (long)assuan_get_pid (entry_ctx));
107 }
108
109
110 /* Unlock the pinentry so that another thread can start one and
111    disconnect that pinentry - we do this after the unlock so that a
112    stalled pinentry does not block other threads.  Fixme: We should
113    have a timeout in Assuan for the disconnect operation. */
114 static int 
115 unlock_pinentry (int rc)
116 {
117   assuan_context_t ctx = entry_ctx;
118
119   entry_ctx = NULL;
120 #ifdef USE_GNU_PTH
121   if (!pth_mutex_release (&entry_lock))
122     {
123       log_error ("failed to release the entry lock\n");
124       if (!rc)
125         rc = gpg_error (GPG_ERR_INTERNAL);
126     }
127 #endif
128   assuan_disconnect (ctx);
129   return rc;
130 }
131
132
133 /* To make sure we leave no secrets in our image after forking of the
134    pinentry, we use this callback. */
135 static void
136 atfork_cb (void *opaque, int where)
137 {
138   if (!where)
139     gcry_control (GCRYCTL_TERM_SECMEM);
140 }
141
142
143 /* Fork off the pin entry if this has not already been done.  Note,
144    that this function must always be used to aquire the lock for the
145    pinentry - we will serialize _all_ pinentry calls.
146  */
147 static int
148 start_pinentry (CTRL ctrl)
149 {
150   int rc;
151   const char *pgmname;
152   ASSUAN_CONTEXT ctx;
153   const char *argv[5];
154   int no_close_list[3];
155   int i;
156
157 #ifdef USE_GNU_PTH
158  {
159    pth_event_t evt;
160
161    evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0));
162    if (!pth_mutex_acquire (&entry_lock, 0, evt))
163     {
164       if (pth_event_occurred (evt))
165         rc = gpg_error (GPG_ERR_TIMEOUT);
166       else
167         rc = gpg_error (GPG_ERR_INTERNAL);
168       pth_event_free (evt, PTH_FREE_THIS);
169       log_error (_("failed to acquire the pinentry lock: %s\n"),
170                  gpg_strerror (rc));
171       return rc;
172     }
173    pth_event_free (evt, PTH_FREE_THIS);
174  }
175 #endif
176
177   if (entry_ctx)
178     return 0; 
179
180   if (opt.verbose)
181     log_info ("starting a new PIN Entry\n");
182       
183   if (fflush (NULL))
184     {
185       gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
186       log_error ("error flushing pending output: %s\n", strerror (errno));
187       return unlock_pinentry (tmperr);
188     }
189
190   if (!opt.pinentry_program || !*opt.pinentry_program)
191     opt.pinentry_program = GNUPG_DEFAULT_PINENTRY;
192   if ( !(pgmname = strrchr (opt.pinentry_program, '/')))
193     pgmname = opt.pinentry_program;
194   else
195     pgmname++;
196
197   argv[0] = pgmname;
198   if (ctrl->display && !opt.keep_display)
199     {
200       argv[1] = "--display";
201       argv[2] = ctrl->display;
202       argv[3] = NULL;
203     }
204   else
205     argv[1] = NULL;
206   
207   i=0;
208   if (!opt.running_detached)
209     {
210       if (log_get_fd () != -1)
211         no_close_list[i++] = log_get_fd ();
212       no_close_list[i++] = fileno (stderr);
213     }
214   no_close_list[i] = -1;
215
216   /* Connect to the pinentry and perform initial handshaking */
217   rc = assuan_pipe_connect2 (&ctx, opt.pinentry_program, (char**)argv,
218                              no_close_list, atfork_cb, NULL);
219   if (rc)
220     {
221       log_error ("can't connect to the PIN entry module: %s\n",
222                  assuan_strerror (rc));
223       return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY));
224     }
225   entry_ctx = ctx;
226
227   if (DBG_ASSUAN)
228     log_debug ("connection to PIN entry established\n");
229
230   rc = assuan_transact (entry_ctx, 
231                         opt.no_grab? "OPTION no-grab":"OPTION grab",
232                         NULL, NULL, NULL, NULL, NULL, NULL);
233   if (rc)
234     return unlock_pinentry (map_assuan_err (rc));
235   if (ctrl->ttyname)
236     {
237       char *optstr;
238       if (asprintf (&optstr, "OPTION ttyname=%s", ctrl->ttyname) < 0 )
239         return unlock_pinentry (out_of_core ());
240       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
241                             NULL);
242       free (optstr);
243       if (rc)
244         return unlock_pinentry (map_assuan_err (rc));
245     }
246   if (ctrl->ttytype)
247     {
248       char *optstr;
249       if (asprintf (&optstr, "OPTION ttytype=%s", ctrl->ttytype) < 0 )
250         return unlock_pinentry (out_of_core ());
251       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
252                             NULL);
253       if (rc)
254         return unlock_pinentry (map_assuan_err (rc));
255     }
256   if (ctrl->lc_ctype)
257     {
258       char *optstr;
259       if (asprintf (&optstr, "OPTION lc-ctype=%s", ctrl->lc_ctype) < 0 )
260         return unlock_pinentry (out_of_core ());
261       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
262                             NULL);
263       if (rc)
264         return unlock_pinentry (map_assuan_err (rc));
265     }
266   if (ctrl->lc_messages)
267     {
268       char *optstr;
269       if (asprintf (&optstr, "OPTION lc-messages=%s", ctrl->lc_messages) < 0 )
270         return unlock_pinentry (out_of_core ());
271       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
272                             NULL);
273       if (rc)
274         return unlock_pinentry (map_assuan_err (rc));
275     }
276   return 0;
277 }
278
279
280 static AssuanError
281 getpin_cb (void *opaque, const void *buffer, size_t length)
282 {
283   struct entry_parm_s *parm = opaque;
284
285   if (!buffer)
286     return 0;
287
288   /* we expect the pin to fit on one line */
289   if (parm->lines || length >= parm->size)
290     return ASSUAN_Too_Much_Data;
291
292   /* fixme: we should make sure that the assuan buffer is allocated in
293      secure memory or read the response byte by byte */
294   memcpy (parm->buffer, buffer, length);
295   parm->buffer[length] = 0;
296   parm->lines++;
297   return 0;
298 }
299
300
301 static int
302 all_digitsp( const char *s)
303 {
304   for (; *s && *s >= '0' && *s <= '9'; s++)
305     ;
306   return !*s;
307 }  
308
309
310 \f
311 /* Call the Entry and ask for the PIN.  We do check for a valid PIN
312    number here and repeat it as long as we have invalid formed
313    numbers. */
314 int
315 agent_askpin (ctrl_t ctrl,
316               const char *desc_text, const char *prompt_text,
317               const char *initial_errtext,
318               struct pin_entry_info_s *pininfo)
319 {
320   int rc;
321   char line[ASSUAN_LINELENGTH];
322   struct entry_parm_s parm;
323   const char *errtext = NULL;
324   int is_pin = 0;
325
326   if (opt.batch)
327     return 0; /* fixme: we should return BAD PIN */
328
329   if (!pininfo || pininfo->max_length < 1)
330     return gpg_error (GPG_ERR_INV_VALUE);
331   if (!desc_text && pininfo->min_digits)
332     desc_text = _("Please enter your PIN, so that the secret key "
333                   "can be unlocked for this session");
334   else if (!desc_text)
335     desc_text = _("Please enter your passphrase, so that the secret key "
336                   "can be unlocked for this session");
337
338   if (prompt_text)
339     is_pin = !!strstr (prompt_text, "PIN");
340   else
341     is_pin = desc_text && strstr (desc_text, "PIN");
342
343   rc = start_pinentry (ctrl);
344   if (rc)
345     return rc;
346
347   snprintf (line, DIM(line)-1, "SETDESC %s", desc_text);
348   line[DIM(line)-1] = 0;
349   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
350   if (rc)
351     return unlock_pinentry (map_assuan_err (rc));
352
353   snprintf (line, DIM(line)-1, "SETPROMPT %s",
354             prompt_text? prompt_text : is_pin? "PIN:" : "Passphrase:");
355   line[DIM(line)-1] = 0;
356   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
357   if (rc)
358     return unlock_pinentry (map_assuan_err (rc));
359
360
361   if (initial_errtext)
362     { 
363       snprintf (line, DIM(line)-1, "SETERROR %s", initial_errtext);
364       line[DIM(line)-1] = 0;
365       rc = assuan_transact (entry_ctx, line,
366                             NULL, NULL, NULL, NULL, NULL, NULL);
367       if (rc)
368         return unlock_pinentry (map_assuan_err (rc));
369     }
370
371   for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
372     {
373       memset (&parm, 0, sizeof parm);
374       parm.size = pininfo->max_length;
375       parm.buffer = pininfo->pin;
376
377       if (errtext)
378         { 
379           /* fixme: should we show the try count? It must be translated */
380           snprintf (line, DIM(line)-1, "SETERROR %s (try %d of %d)",
381                     errtext, pininfo->failed_tries+1, pininfo->max_tries);
382           line[DIM(line)-1] = 0;
383           rc = assuan_transact (entry_ctx, line,
384                                 NULL, NULL, NULL, NULL, NULL, NULL);
385           if (rc)
386             return unlock_pinentry (map_assuan_err (rc));
387           errtext = NULL;
388         }
389       
390       rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
391                             NULL, NULL, NULL, NULL);
392       if (rc == ASSUAN_Too_Much_Data)
393         errtext = is_pin? _("PIN too long")
394                         : _("Passphrase too long");
395       else if (rc)
396         return unlock_pinentry (map_assuan_err (rc));
397
398       if (!errtext && pininfo->min_digits)
399         {
400           /* do some basic checks on the entered PIN. */
401           if (!all_digitsp (pininfo->pin))
402             errtext = _("Invalid characters in PIN");
403           else if (pininfo->max_digits
404                    && strlen (pininfo->pin) > pininfo->max_digits)
405             errtext = _("PIN too long");
406           else if (strlen (pininfo->pin) < pininfo->min_digits)
407             errtext = _("PIN too short");
408         }
409
410       if (!errtext && pininfo->check_cb)
411         {
412           /* More checks by utilizing the optional callback. */
413           pininfo->cb_errtext = NULL;
414           rc = pininfo->check_cb (pininfo);
415           if (rc == -1 && pininfo->cb_errtext)
416             errtext = pininfo->cb_errtext;
417           else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
418                    || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
419             errtext = (is_pin? _("Bad PIN")
420                        : _("Bad Passphrase"));
421           else if (rc)
422             return unlock_pinentry (map_assuan_err (rc));
423         }
424
425       if (!errtext)
426         return unlock_pinentry (0); /* okay, got a PIN or passphrase */
427     }
428
429   return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
430                           : GPG_ERR_BAD_PASSPHRASE));
431 }
432
433
434 \f
435 /* Ask for the passphrase using the supplied arguments.  The
436    passphrase is returned in RETPASS as an hex encoded string to be
437    freed by the caller */
438 int 
439 agent_get_passphrase (CTRL ctrl,
440                       char **retpass, const char *desc, const char *prompt,
441                       const char *errtext)
442 {
443
444   int rc;
445   char line[ASSUAN_LINELENGTH];
446   struct entry_parm_s parm;
447   unsigned char *p, *hexstring;
448   int i;
449
450   *retpass = NULL;
451   if (opt.batch)
452     return gpg_error (GPG_ERR_BAD_PASSPHRASE); 
453
454   rc = start_pinentry (ctrl);
455   if (rc)
456     return rc;
457
458   if (!prompt)
459     prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase");
460
461
462   if (desc)
463     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
464   else
465     snprintf (line, DIM(line)-1, "RESET");
466   line[DIM(line)-1] = 0;
467   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
468   if (rc)
469     return unlock_pinentry (map_assuan_err (rc));
470
471   snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt);
472   line[DIM(line)-1] = 0;
473   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
474   if (rc)
475     return unlock_pinentry (map_assuan_err (rc));
476
477   if (errtext)
478     {
479       snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
480       line[DIM(line)-1] = 0;
481       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
482       if (rc)
483         return unlock_pinentry (map_assuan_err (rc));
484     }
485
486   memset (&parm, 0, sizeof parm);
487   parm.size = ASSUAN_LINELENGTH/2 - 5;
488   parm.buffer = gcry_malloc_secure (parm.size+10);
489   if (!parm.buffer)
490     return unlock_pinentry (out_of_core ());
491
492   assuan_begin_confidential (entry_ctx);
493   rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, NULL, NULL, NULL, NULL);
494   if (rc)
495     {
496       xfree (parm.buffer);
497       return unlock_pinentry (map_assuan_err (rc));
498     }
499   
500   hexstring = gcry_malloc_secure (strlen (parm.buffer)*2+1);
501   if (!hexstring)
502     {
503       gpg_error_t tmperr = out_of_core ();
504       xfree (parm.buffer);
505       return unlock_pinentry (tmperr);
506     }
507
508   for (i=0, p=parm.buffer; *p; p++, i += 2)
509     sprintf (hexstring+i, "%02X", *p);
510   
511   xfree (parm.buffer);
512   *retpass = hexstring;
513   return unlock_pinentry (0);
514 }
515
516
517 \f
518 /* Pop up the PIN-entry, display the text and the prompt and ask the
519    user to confirm this.  We return 0 for success, ie. the used
520    confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
521    other error. */
522 int 
523 agent_get_confirmation (CTRL ctrl,
524                         const char *desc, const char *ok, const char *cancel)
525 {
526   int rc;
527   char line[ASSUAN_LINELENGTH];
528
529   rc = start_pinentry (ctrl);
530   if (rc)
531     return rc;
532
533   if (desc)
534     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
535   else
536     snprintf (line, DIM(line)-1, "RESET");
537   line[DIM(line)-1] = 0;
538   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
539   if (rc)
540     return unlock_pinentry (map_assuan_err (rc));
541
542   if (ok)
543     {
544       snprintf (line, DIM(line)-1, "SETOK %s", ok);
545       line[DIM(line)-1] = 0;
546       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
547       if (rc)
548         return unlock_pinentry (map_assuan_err (rc));
549     }
550   if (cancel)
551     {
552       snprintf (line, DIM(line)-1, "SETCANCEL %s", cancel);
553       line[DIM(line)-1] = 0;
554       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
555       if (rc)
556         return unlock_pinentry (map_assuan_err (rc));
557     }
558
559   rc = assuan_transact (entry_ctx, "CONFIRM", NULL, NULL, NULL, NULL, NULL, NULL);
560   return unlock_pinentry (map_assuan_err (rc));
561 }
562
563
564