Allow to cancel marktrusted.
[gnupg.git] / agent / call-pinentry.c
1 /* call-pinnetry.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 #include <config.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <assert.h>
29 #include <unistd.h>
30 #include <sys/stat.h>
31 #ifndef HAVE_W32_SYSTEM
32 #include <sys/wait.h>
33 #endif
34 #include <pth.h>
35 #include <assuan.h>
36
37 #include "agent.h"
38 #include "i18n.h"
39
40 #ifdef _POSIX_OPEN_MAX
41 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
42 #else
43 #define MAX_OPEN_FDS 20
44 #endif
45
46
47 /* Because access to the pinentry must be serialized (it is and shall
48    be a global mutual dialog) we should better timeout further
49    requests after some time.  2 minutes seem to be a reasonable
50    time. */
51 #define LOCK_TIMEOUT  (1*60)
52
53 /* The assuan context of the current pinentry. */
54 static assuan_context_t entry_ctx;
55
56 /* The control variable of the connection owning the current pinentry.
57    This is only valid if ENTRY_CTX is not NULL.  Note, that we care
58    only about the value of the pointer and that it should never be
59    dereferenced.  */
60 static ctrl_t entry_owner;
61
62 /* A mutex used to serialize access to the pinentry. */
63 static pth_mutex_t entry_lock;
64
65 /* The thread ID of the popup working thread. */
66 static pth_t  popup_tid;
67
68 /* A flag used in communication between the popup working thread and
69    its stop function. */
70 static int popup_finished;
71
72
73
74 /* Data to be passed to our callbacks, */
75 struct entry_parm_s
76 {
77   int lines;
78   size_t size;
79   unsigned char *buffer;
80 };
81
82
83
84 \f
85 /* This function must be called once to initialize this module.  This
86    has to be done before a second thread is spawned.  We can't do the
87    static initialization because Pth emulation code might not be able
88    to do a static init; in particular, it is not possible for W32. */
89 void
90 initialize_module_query (void)
91 {
92   static int initialized;
93
94   if (!initialized)
95     {
96       if (pth_mutex_init (&entry_lock))
97         initialized = 1;
98     }
99 }
100
101
102
103 static void
104 dump_mutex_state (pth_mutex_t *m)
105 {
106   if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
107     log_printf ("not_initialized");
108   else if (!(m->mx_state & PTH_MUTEX_LOCKED))
109     log_printf ("not_locked");
110   else
111     log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
112 }
113
114
115 /* This function may be called to print infromation pertaining to the
116    current state of this module to the log. */
117 void
118 agent_query_dump_state (void)
119 {
120   log_info ("agent_query_dump_state: entry_lock=");
121   dump_mutex_state (&entry_lock);
122   log_printf ("\n");
123   log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n",
124             entry_ctx, (long)assuan_get_pid (entry_ctx), popup_tid);
125 }
126
127 /* Called to make sure that a popup window owned by the current
128    connection gets closed. */
129 void
130 agent_reset_query (ctrl_t ctrl)
131 {
132   if (entry_ctx && popup_tid && entry_owner == ctrl)
133     {
134       agent_popup_message_stop (ctrl);
135     }
136 }
137
138
139 /* Unlock the pinentry so that another thread can start one and
140    disconnect that pinentry - we do this after the unlock so that a
141    stalled pinentry does not block other threads.  Fixme: We should
142    have a timeout in Assuan for the disconnect operation. */
143 static int 
144 unlock_pinentry (int rc)
145 {
146   assuan_context_t ctx = entry_ctx;
147
148   entry_ctx = NULL;
149   if (!pth_mutex_release (&entry_lock))
150     {
151       log_error ("failed to release the entry lock\n");
152       if (!rc)
153         rc = gpg_error (GPG_ERR_INTERNAL);
154     }
155   assuan_disconnect (ctx);
156   return rc;
157 }
158
159
160 /* To make sure we leave no secrets in our image after forking of the
161    pinentry, we use this callback. */
162 static void
163 atfork_cb (void *opaque, int where)
164 {
165   if (!where)
166     gcry_control (GCRYCTL_TERM_SECMEM);
167 }
168
169
170 /* Fork off the pin entry if this has not already been done.  Note,
171    that this function must always be used to aquire the lock for the
172    pinentry - we will serialize _all_ pinentry calls.
173  */
174 static int
175 start_pinentry (ctrl_t ctrl)
176 {
177   int rc;
178   const char *pgmname;
179   assuan_context_t ctx;
180   const char *argv[5];
181   int no_close_list[3];
182   int i;
183   pth_event_t evt;
184
185   evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0));
186   if (!pth_mutex_acquire (&entry_lock, 0, evt))
187     {
188       if (pth_event_occurred (evt))
189         rc = gpg_error (GPG_ERR_TIMEOUT);
190       else
191         rc = gpg_error (GPG_ERR_INTERNAL);
192       pth_event_free (evt, PTH_FREE_THIS);
193       log_error (_("failed to acquire the pinentry lock: %s\n"),
194                  gpg_strerror (rc));
195       return rc;
196     }
197   pth_event_free (evt, PTH_FREE_THIS);
198
199   entry_owner = ctrl;
200
201   if (entry_ctx)
202     return 0; 
203
204   if (opt.verbose)
205     log_info ("starting a new PIN Entry\n");
206       
207   if (fflush (NULL))
208     {
209       gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
210       log_error ("error flushing pending output: %s\n", strerror (errno));
211       return unlock_pinentry (tmperr);
212     }
213
214   if (!opt.pinentry_program || !*opt.pinentry_program)
215     opt.pinentry_program = GNUPG_DEFAULT_PINENTRY;
216   if ( !(pgmname = strrchr (opt.pinentry_program, '/')))
217     pgmname = opt.pinentry_program;
218   else
219     pgmname++;
220
221   argv[0] = pgmname;
222   if (ctrl->display && !opt.keep_display)
223     {
224       argv[1] = "--display";
225       argv[2] = ctrl->display;
226       argv[3] = NULL;
227     }
228   else
229     argv[1] = NULL;
230   
231   i=0;
232   if (!opt.running_detached)
233     {
234       if (log_get_fd () != -1)
235         no_close_list[i++] = log_get_fd ();
236       no_close_list[i++] = fileno (stderr);
237     }
238   no_close_list[i] = -1;
239
240   /* Connect to the pinentry and perform initial handshaking */
241   rc = assuan_pipe_connect_ext (&ctx, opt.pinentry_program, argv,
242                                 no_close_list, atfork_cb, NULL, 0);
243   if (rc)
244     {
245       log_error ("can't connect to the PIN entry module: %s\n",
246                  gpg_strerror (rc));
247       return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY));
248     }
249   entry_ctx = ctx;
250
251   if (DBG_ASSUAN)
252     log_debug ("connection to PIN entry established\n");
253
254   rc = assuan_transact (entry_ctx, 
255                         opt.no_grab? "OPTION no-grab":"OPTION grab",
256                         NULL, NULL, NULL, NULL, NULL, NULL);
257   if (rc)
258     return unlock_pinentry (rc);
259   if (ctrl->ttyname)
260     {
261       char *optstr;
262       if (asprintf (&optstr, "OPTION ttyname=%s", ctrl->ttyname) < 0 )
263         return unlock_pinentry (out_of_core ());
264       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
265                             NULL);
266       free (optstr);
267       if (rc)
268         return unlock_pinentry (rc);
269     }
270   if (ctrl->ttytype)
271     {
272       char *optstr;
273       if (asprintf (&optstr, "OPTION ttytype=%s", ctrl->ttytype) < 0 )
274         return unlock_pinentry (out_of_core ());
275       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
276                             NULL);
277       if (rc)
278         return unlock_pinentry (rc);
279     }
280   if (ctrl->lc_ctype)
281     {
282       char *optstr;
283       if (asprintf (&optstr, "OPTION lc-ctype=%s", ctrl->lc_ctype) < 0 )
284         return unlock_pinentry (out_of_core ());
285       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
286                             NULL);
287       if (rc)
288         return unlock_pinentry (rc);
289     }
290   if (ctrl->lc_messages)
291     {
292       char *optstr;
293       if (asprintf (&optstr, "OPTION lc-messages=%s", ctrl->lc_messages) < 0 )
294         return unlock_pinentry (out_of_core ());
295       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
296                             NULL);
297       if (rc)
298         return unlock_pinentry (rc);
299     }
300   return 0;
301 }
302
303
304 static int
305 getpin_cb (void *opaque, const void *buffer, size_t length)
306 {
307   struct entry_parm_s *parm = opaque;
308
309   if (!buffer)
310     return 0;
311
312   /* we expect the pin to fit on one line */
313   if (parm->lines || length >= parm->size)
314     return gpg_error (GPG_ERR_ASS_TOO_MUCH_DATA);
315
316   /* fixme: we should make sure that the assuan buffer is allocated in
317      secure memory or read the response byte by byte */
318   memcpy (parm->buffer, buffer, length);
319   parm->buffer[length] = 0;
320   parm->lines++;
321   return 0;
322 }
323
324
325 static int
326 all_digitsp( const char *s)
327 {
328   for (; *s && *s >= '0' && *s <= '9'; s++)
329     ;
330   return !*s;
331 }  
332
333
334 \f
335 /* Call the Entry and ask for the PIN.  We do check for a valid PIN
336    number here and repeat it as long as we have invalid formed
337    numbers. */
338 int
339 agent_askpin (ctrl_t ctrl,
340               const char *desc_text, const char *prompt_text,
341               const char *initial_errtext,
342               struct pin_entry_info_s *pininfo)
343 {
344   int rc;
345   char line[ASSUAN_LINELENGTH];
346   struct entry_parm_s parm;
347   const char *errtext = NULL;
348   int is_pin = 0;
349
350   if (opt.batch)
351     return 0; /* fixme: we should return BAD PIN */
352
353   if (!pininfo || pininfo->max_length < 1)
354     return gpg_error (GPG_ERR_INV_VALUE);
355   if (!desc_text && pininfo->min_digits)
356     desc_text = _("Please enter your PIN, so that the secret key "
357                   "can be unlocked for this session");
358   else if (!desc_text)
359     desc_text = _("Please enter your passphrase, so that the secret key "
360                   "can be unlocked for this session");
361
362   if (prompt_text)
363     is_pin = !!strstr (prompt_text, "PIN");
364   else
365     is_pin = desc_text && strstr (desc_text, "PIN");
366
367   rc = start_pinentry (ctrl);
368   if (rc)
369     return rc;
370
371   snprintf (line, DIM(line)-1, "SETDESC %s", desc_text);
372   line[DIM(line)-1] = 0;
373   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
374   if (rc)
375     return unlock_pinentry (rc);
376
377   snprintf (line, DIM(line)-1, "SETPROMPT %s",
378             prompt_text? prompt_text : is_pin? "PIN:" : "Passphrase:");
379   line[DIM(line)-1] = 0;
380   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
381   if (rc)
382     return unlock_pinentry (rc);
383
384
385   if (initial_errtext)
386     { 
387       snprintf (line, DIM(line)-1, "SETERROR %s", initial_errtext);
388       line[DIM(line)-1] = 0;
389       rc = assuan_transact (entry_ctx, line,
390                             NULL, NULL, NULL, NULL, NULL, NULL);
391       if (rc)
392         return unlock_pinentry (rc);
393     }
394
395   for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
396     {
397       memset (&parm, 0, sizeof parm);
398       parm.size = pininfo->max_length;
399       parm.buffer = (unsigned char*)pininfo->pin;
400
401       if (errtext)
402         { 
403           /* fixme: should we show the try count? It must be translated */
404           snprintf (line, DIM(line)-1, "SETERROR %s (try %d of %d)",
405                     errtext, pininfo->failed_tries+1, pininfo->max_tries);
406           line[DIM(line)-1] = 0;
407           rc = assuan_transact (entry_ctx, line,
408                                 NULL, NULL, NULL, NULL, NULL, NULL);
409           if (rc)
410             return unlock_pinentry (rc);
411           errtext = NULL;
412         }
413       
414       rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
415                             NULL, NULL, NULL, NULL);
416       /* Most pinentries out in the wild return the old Assuan error code
417          for canceled which gets translated to an assuan Cancel error and
418          not to the code for a user cancel.  Fix this here. */
419       if (rc && gpg_err_source (rc)
420           && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
421         rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
422
423       if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
424         errtext = is_pin? _("PIN too long")
425                         : _("Passphrase too long");
426       else if (rc)
427         return unlock_pinentry (rc);
428
429       if (!errtext && pininfo->min_digits)
430         {
431           /* do some basic checks on the entered PIN. */
432           if (!all_digitsp (pininfo->pin))
433             errtext = _("Invalid characters in PIN");
434           else if (pininfo->max_digits
435                    && strlen (pininfo->pin) > pininfo->max_digits)
436             errtext = _("PIN too long");
437           else if (strlen (pininfo->pin) < pininfo->min_digits)
438             errtext = _("PIN too short");
439         }
440
441       if (!errtext && pininfo->check_cb)
442         {
443           /* More checks by utilizing the optional callback. */
444           pininfo->cb_errtext = NULL;
445           rc = pininfo->check_cb (pininfo);
446           if (rc == -1 && pininfo->cb_errtext)
447             errtext = pininfo->cb_errtext;
448           else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
449                    || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
450             errtext = (is_pin? _("Bad PIN")
451                        : _("Bad Passphrase"));
452           else if (rc)
453             return unlock_pinentry (rc);
454         }
455
456       if (!errtext)
457         return unlock_pinentry (0); /* okay, got a PIN or passphrase */
458     }
459
460   return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
461                           : GPG_ERR_BAD_PASSPHRASE));
462 }
463
464
465 \f
466 /* Ask for the passphrase using the supplied arguments.  The returned
467    passphrase needs to be freed by the caller. */
468 int 
469 agent_get_passphrase (ctrl_t ctrl,
470                       char **retpass, const char *desc, const char *prompt,
471                       const char *errtext)
472 {
473
474   int rc;
475   char line[ASSUAN_LINELENGTH];
476   struct entry_parm_s parm;
477
478   *retpass = NULL;
479   if (opt.batch)
480     return gpg_error (GPG_ERR_BAD_PASSPHRASE); 
481
482   rc = start_pinentry (ctrl);
483   if (rc)
484     return rc;
485
486   if (!prompt)
487     prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase");
488
489
490   if (desc)
491     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
492   else
493     snprintf (line, DIM(line)-1, "RESET");
494   line[DIM(line)-1] = 0;
495   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
496   if (rc)
497     return unlock_pinentry (rc);
498
499   snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt);
500   line[DIM(line)-1] = 0;
501   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
502   if (rc)
503     return unlock_pinentry (rc);
504
505   if (errtext)
506     {
507       snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
508       line[DIM(line)-1] = 0;
509       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
510       if (rc)
511         return unlock_pinentry (rc);
512     }
513
514   memset (&parm, 0, sizeof parm);
515   parm.size = ASSUAN_LINELENGTH/2 - 5;
516   parm.buffer = gcry_malloc_secure (parm.size+10);
517   if (!parm.buffer)
518     return unlock_pinentry (out_of_core ());
519
520   assuan_begin_confidential (entry_ctx);
521   rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
522                         NULL, NULL, NULL, NULL);
523   /* Most pinentries out in the wild return the old Assuan error code
524      for canceled which gets translated to an assuan Cancel error and
525      not to the code for a user cancel.  Fix this here. */
526   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
527     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
528   if (rc)
529     xfree (parm.buffer);
530   else
531     *retpass = parm.buffer;
532   return unlock_pinentry (rc);
533 }
534
535
536 \f
537 /* Pop up the PIN-entry, display the text and the prompt and ask the
538    user to confirm this.  We return 0 for success, ie. the user
539    confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
540    other error. */
541 int 
542 agent_get_confirmation (ctrl_t ctrl,
543                         const char *desc, const char *ok, const char *cancel)
544 {
545   int rc;
546   char line[ASSUAN_LINELENGTH];
547
548   rc = start_pinentry (ctrl);
549   if (rc)
550     return rc;
551
552   if (desc)
553     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
554   else
555     snprintf (line, DIM(line)-1, "RESET");
556   line[DIM(line)-1] = 0;
557   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
558   /* Most pinentries out in the wild return the old Assuan error code
559      for canceled which gets translated to an assuan Cancel error and
560      not to the code for a user cancel.  Fix this here. */
561   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
562     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
563
564   if (rc)
565     return unlock_pinentry (rc);
566
567   if (ok)
568     {
569       snprintf (line, DIM(line)-1, "SETOK %s", ok);
570       line[DIM(line)-1] = 0;
571       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
572       if (rc)
573         return unlock_pinentry (rc);
574     }
575   if (cancel)
576     {
577       snprintf (line, DIM(line)-1, "SETCANCEL %s", cancel);
578       line[DIM(line)-1] = 0;
579       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
580       if (rc)
581         return unlock_pinentry (rc);
582     }
583
584   rc = assuan_transact (entry_ctx, "CONFIRM", NULL, NULL, NULL, NULL, NULL, NULL);
585   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
586     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
587
588   return unlock_pinentry (rc);
589 }
590
591
592 /* The thread running the popup message. */
593 static void *
594 popup_message_thread (void *arg)
595 {
596   assuan_transact (entry_ctx, "CONFIRM", NULL, NULL, NULL, NULL, NULL, NULL);
597   popup_finished = 1;
598   return NULL;
599 }
600
601
602 /* Pop up a message window similar to the confirm one but keep it open
603    until agent_popup_message_stop has been called.  It is crucial for
604    the caller to make sure that the stop function gets called as soon
605    as the message is not anymore required becuase the message is
606    system modal and all other attempts to use the pinentry will fail
607    (after a timeout). */
608 int 
609 agent_popup_message_start (ctrl_t ctrl, const char *desc,
610                            const char *ok_btn, const char *cancel_btn)
611 {
612   int rc;
613   char line[ASSUAN_LINELENGTH];
614   pth_attr_t tattr;
615
616   rc = start_pinentry (ctrl);
617   if (rc)
618     return rc;
619
620   if (desc)
621     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
622   else
623     snprintf (line, DIM(line)-1, "RESET");
624   line[DIM(line)-1] = 0;
625   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
626   if (rc)
627     return unlock_pinentry (rc);
628
629   if (ok_btn)
630     {
631       snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
632       line[DIM(line)-1] = 0;
633       rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
634       if (rc)
635         return unlock_pinentry (rc);
636     }
637   if (cancel_btn)
638     {
639       snprintf (line, DIM(line)-1, "SETCANCEL %s", cancel_btn);
640       line[DIM(line)-1] = 0;
641       rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
642       if (rc)
643         return unlock_pinentry (rc);
644     }
645
646   tattr = pth_attr_new();
647   pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1);
648   pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
649   pth_attr_set (tattr, PTH_ATTR_NAME, "popup-message");
650
651   popup_finished = 0;
652   popup_tid = pth_spawn (tattr, popup_message_thread, NULL);
653   if (!popup_tid)
654     {
655       rc = gpg_error_from_syserror ();
656       log_error ("error spawning popup message handler: %s\n",
657                  strerror (errno) );
658       pth_attr_destroy (tattr);
659       return unlock_pinentry (rc);
660     }
661   pth_attr_destroy (tattr);
662
663   return 0;
664 }
665
666 /* Close a popup window. */
667 void
668 agent_popup_message_stop (ctrl_t ctrl)
669 {
670   int rc;
671   pid_t pid;
672
673   if (!popup_tid || !entry_ctx)
674     {
675       log_debug ("agent_popup_message_stop called with no active popup\n");
676       return; 
677     }
678
679   pid = assuan_get_pid (entry_ctx);
680   if (pid == (pid_t)(-1))
681     ; /* No pid available can't send a kill. */
682   else if (popup_finished)
683     ; /* Already finished and ready for joining. */
684   else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
685     { /* The daemon already died.  No need to send a kill.  However
686          because we already waited for the process, we need to tell
687          assuan that it should not wait again (done by
688          unlock_pinentry). */
689       if (rc == pid)
690         assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1);
691     }
692   else
693     kill (pid, SIGINT);
694
695   /* Now wait for the thread to terminate. */
696   rc = pth_join (popup_tid, NULL);
697   if (!rc)
698     log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
699                strerror (errno));
700   popup_tid = NULL;
701   entry_owner = NULL;
702
703   /* Now we can close the connection. */
704   unlock_pinentry (0);
705 }
706
707