Use more warning options with modern GCCs.
[gnupg.git] / agent / call-scd.c
1 /* call-scd.c - fork of the scdaemon to do SC operations
2  *      Copyright (C) 2001, 2002, 2005, 2007 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 <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <assert.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #ifndef HAVE_W32_SYSTEM
32 #include <sys/wait.h>
33 #endif
34 #include <pth.h>
35
36 #include "agent.h"
37 #include <assuan.h>
38
39 #ifdef _POSIX_OPEN_MAX
40 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
41 #else
42 #define MAX_OPEN_FDS 20
43 #endif
44
45 /* Definition of module local data of the CTRL structure.  */
46 struct scd_local_s
47 {
48   /* We keep a list of all allocated context with a an achnor at
49      SCD_LOCAL_LIST (see below). */
50   struct scd_local_s *next_local;
51
52   /* We need to get back to the ctrl object actually referencing this
53      structure.  This is really an awkward way of enumerint the lcoal
54      contects.  A much cleaner way would be to keep a global list of
55      ctrl objects to enumerate them.  */
56   ctrl_t ctrl_backlink;
57
58   assuan_context_t ctx; /* NULL or session context for the SCdaemon
59                            used with this connection. */
60   int locked;           /* This flag is used to assert proper use of
61                            start_scd and unlock_scd. */
62
63 };
64
65
66 /* Callback parameter for learn card */
67 struct learn_parm_s
68 {
69   void (*kpinfo_cb)(void*, const char *);
70   void *kpinfo_cb_arg;
71   void (*certinfo_cb)(void*, const char *);
72   void *certinfo_cb_arg;
73   void (*sinfo_cb)(void*, const char *, size_t, const char *);
74   void *sinfo_cb_arg;
75 };
76
77 struct inq_needpin_s 
78 {
79   assuan_context_t ctx;
80   int (*getpin_cb)(void *, const char *, char*, size_t);
81   void *getpin_cb_arg;
82   assuan_context_t passthru;  /* If not NULL, pass unknown inquiries
83                                  up to the caller.  */
84 };
85
86
87 /* To keep track of all active SCD contexts, we keep a linked list
88    anchored at this variable. */
89 static struct scd_local_s *scd_local_list;
90
91 /* A Mutex used inside the start_scd function. */
92 static pth_mutex_t start_scd_lock;
93
94 /* A malloced string with the name of the socket to be used for
95    additional connections.  May be NULL if not provided by
96    SCdaemon. */
97 static char *socket_name;
98
99 /* The context of the primary connection.  This is also used as a flag
100    to indicate whether the scdaemon has been started. */
101 static assuan_context_t primary_scd_ctx;
102
103 /* To allow reuse of the primary connection, the following flag is set
104    to true if the primary context has been reset and is not in use by
105    any connection. */
106 static int primary_scd_ctx_reusable;
107
108
109
110 /* Local prototypes.  */
111 static assuan_error_t membuf_data_cb (void *opaque,
112                                       const void *buffer, size_t length);
113
114
115
116 \f
117 /* This function must be called once to initialize this module.  This
118    has to be done before a second thread is spawned.  We can't do the
119    static initialization because Pth emulation code might not be able
120    to do a static init; in particular, it is not possible for W32. */
121 void
122 initialize_module_call_scd (void)
123 {
124   static int initialized;
125
126   if (!initialized)
127     {
128       if (!pth_mutex_init (&start_scd_lock))
129         log_fatal ("error initializing mutex: %s\n", strerror (errno));
130       initialized = 1;
131     }
132 }
133
134
135 static void
136 dump_mutex_state (pth_mutex_t *m)
137 {
138 #ifdef _W32_PTH_H
139   log_printf ("unknown under W32");
140 #else
141   if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
142     log_printf ("not_initialized");
143   else if (!(m->mx_state & PTH_MUTEX_LOCKED))
144     log_printf ("not_locked");
145   else
146     log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
147 #endif
148 }
149
150
151 /* This function may be called to print infromation pertaining to the
152    current state of this module to the log. */
153 void
154 agent_scd_dump_state (void)
155 {
156   log_info ("agent_scd_dump_state: scd_lock=");
157   dump_mutex_state (&start_scd_lock);
158   log_printf ("\n");
159   log_info ("agent_scd_dump_state: primary_scd_ctx=%p pid=%ld reusable=%d\n",
160             primary_scd_ctx, 
161             (long)assuan_get_pid (primary_scd_ctx),
162             primary_scd_ctx_reusable);
163   if (socket_name)
164     log_info ("agent_scd_dump_state: socket=`%s'\n", socket_name);
165 }
166
167
168 /* The unlock_scd function shall be called after having accessed the
169    SCD.  It is currently not very useful but gives an opportunity to
170    keep track of connections currently calling SCD.  Note that the
171    "lock" operation is done by the start_scd() function which must be
172    called and error checked before any SCD operation.  CTRL is the
173    usual connection context and RC the error code to be passed trhough
174    the function. */
175 static int 
176 unlock_scd (ctrl_t ctrl, int rc)
177 {
178   if (ctrl->scd_local->locked != 1)
179     {
180       log_error ("unlock_scd: invalid lock count (%d)\n",
181                  ctrl->scd_local->locked);
182       if (!rc)
183         rc = gpg_error (GPG_ERR_INTERNAL);
184     }
185   ctrl->scd_local->locked = 0;
186   return rc;
187 }
188
189 /* To make sure we leave no secrets in our image after forking of the
190    scdaemon, we use this callback. */
191 static void
192 atfork_cb (void *opaque, int where)
193 {
194   if (!where)
195     gcry_control (GCRYCTL_TERM_SECMEM);
196 }
197
198
199 /* Fork off the SCdaemon if this has not already been done.  Lock the
200    daemon and make sure that a proper context has been setup in CTRL.
201    This function might also lock the daemon, which means that the
202    caller must call unlock_scd after this fucntion has returned
203    success and the actual Assuan transaction been done. */
204 static int
205 start_scd (ctrl_t ctrl)
206 {
207   gpg_error_t err = 0;
208   const char *pgmname;
209   assuan_context_t ctx;
210   const char *argv[3];
211   int no_close_list[3];
212   int i;
213   int rc;
214
215   if (opt.disable_scdaemon)
216     return gpg_error (GPG_ERR_NOT_SUPPORTED);
217
218   /* If this is the first call for this session, setup the local data
219      structure. */
220   if (!ctrl->scd_local)
221     {
222       ctrl->scd_local = xtrycalloc (1, sizeof *ctrl->scd_local);
223       if (!ctrl->scd_local)
224         return gpg_error_from_syserror ();
225       ctrl->scd_local->ctrl_backlink = ctrl;
226       ctrl->scd_local->next_local = scd_local_list;
227       scd_local_list = ctrl->scd_local;
228     }
229
230
231   /* Assert that the lock count is as expected. */
232   if (ctrl->scd_local->locked)
233     {
234       log_error ("start_scd: invalid lock count (%d)\n",
235                  ctrl->scd_local->locked);
236       return gpg_error (GPG_ERR_INTERNAL);
237     }
238   ctrl->scd_local->locked++;
239
240   if (ctrl->scd_local->ctx)
241     return 0; /* Okay, the context is fine.  We used to test for an
242                  alive context here and do an disconnect.  Now that we
243                  have a ticker function to check for it, it is easier
244                  not to check here but to let the connection run on an
245                  error instead. */
246
247
248   /* We need to protect the following code. */
249   if (!pth_mutex_acquire (&start_scd_lock, 0, NULL))
250     {
251       log_error ("failed to acquire the start_scd lock: %s\n",
252                  strerror (errno));
253       return gpg_error (GPG_ERR_INTERNAL);
254     }
255
256   /* Check whether the pipe server has already been started and in
257      this case either reuse a lingering pipe connection or establish a
258      new socket based one. */
259   if (primary_scd_ctx && primary_scd_ctx_reusable)
260     {
261       ctx = primary_scd_ctx;
262       primary_scd_ctx_reusable = 0;
263       if (opt.verbose)
264         log_info ("new connection to SCdaemon established (reusing)\n");
265       goto leave;
266     }
267
268   if (socket_name)
269     {
270       rc = assuan_socket_connect (&ctx, socket_name, 0);
271       if (rc)
272         {
273           log_error ("can't connect to socket `%s': %s\n",
274                      socket_name, gpg_strerror (rc));
275           err = gpg_error (GPG_ERR_NO_SCDAEMON);
276           goto leave;
277         }
278
279       if (opt.verbose)
280         log_info ("new connection to SCdaemon established\n");
281       goto leave;
282     }
283
284   if (primary_scd_ctx)
285     {
286       log_info ("SCdaemon is running but won't accept further connections\n");
287       err = gpg_error (GPG_ERR_NO_SCDAEMON);
288       goto leave;
289     }
290
291   /* Nope, it has not been started.  Fire it up now. */
292   if (opt.verbose)
293     log_info ("no running SCdaemon - starting it\n");
294       
295   if (fflush (NULL))
296     {
297 #ifndef HAVE_W32_SYSTEM
298       err = gpg_error_from_syserror ();
299 #endif
300       log_error ("error flushing pending output: %s\n", strerror (errno));
301       /* At least Windows XP fails here with EBADF.  According to docs
302          and Wine an fflush(NULL) is the same as _flushall.  However
303          the Wime implementaion does not flush stdin,stdout and stderr
304          - see above.  Lets try to ignore the error. */
305 #ifndef HAVE_W32_SYSTEM
306       goto leave;
307 #endif
308     }
309
310   if (!opt.scdaemon_program || !*opt.scdaemon_program)
311     opt.scdaemon_program = gnupg_module_name (GNUPG_MODULE_NAME_SCDAEMON);
312   if ( !(pgmname = strrchr (opt.scdaemon_program, '/')))
313     pgmname = opt.scdaemon_program;
314   else
315     pgmname++;
316
317   argv[0] = pgmname;
318   argv[1] = "--multi-server";
319   argv[2] = NULL;
320
321   i=0;
322   if (!opt.running_detached)
323     {
324       if (log_get_fd () != -1)
325         no_close_list[i++] = log_get_fd ();
326       no_close_list[i++] = fileno (stderr);
327     }
328   no_close_list[i] = -1;
329
330   /* Connect to the pinentry and perform initial handshaking.  Use
331      detached flag (128) so that under W32 SCDAEMON does not show up a
332      new window.  */
333   rc = assuan_pipe_connect_ext (&ctx, opt.scdaemon_program, argv,
334                                 no_close_list, atfork_cb, NULL, 128);
335   if (rc)
336     {
337       log_error ("can't connect to the SCdaemon: %s\n",
338                  gpg_strerror (rc));
339       err = gpg_error (GPG_ERR_NO_SCDAEMON);
340       goto leave;
341     }
342
343   if (opt.verbose)
344     log_debug ("first connection to SCdaemon established\n");
345
346   if (DBG_ASSUAN)
347     assuan_set_log_stream (ctx, log_get_stream ());
348
349   /* Get the name of the additional socket opened by scdaemon. */
350   {
351     membuf_t data;
352     unsigned char *databuf;
353     size_t datalen;
354
355     xfree (socket_name);
356     socket_name = NULL;
357     init_membuf (&data, 256);
358     assuan_transact (ctx, "GETINFO socket_name",
359                      membuf_data_cb, &data, NULL, NULL, NULL, NULL);
360
361     databuf = get_membuf (&data, &datalen);
362     if (databuf && datalen)
363       {
364         socket_name = xtrymalloc (datalen + 1);
365         if (!socket_name)
366           log_error ("warning: can't store socket name: %s\n",
367                      strerror (errno));
368         else
369           {
370             memcpy (socket_name, databuf, datalen);
371             socket_name[datalen] = 0;
372             if (DBG_ASSUAN)
373               log_debug ("additional connections at `%s'\n", socket_name);
374           }
375       }
376     xfree (databuf);
377   }
378
379   /* Tell the scdaemon we want him to send us an event signal. */
380   {
381     char buf[100];
382
383 #ifdef HAVE_W32_SYSTEM
384     snprintf (buf, sizeof buf, "OPTION event-signal=%lx", 
385               (unsigned long)get_agent_scd_notify_event ());
386 #else
387     snprintf (buf, sizeof buf, "OPTION event-signal=%d", SIGUSR2);
388 #endif
389     assuan_transact (ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
390   }
391
392   primary_scd_ctx = ctx;
393   primary_scd_ctx_reusable = 0;
394
395  leave:
396   if (err)
397     {
398       unlock_scd (ctrl, err);
399     } 
400   else
401     {
402       ctrl->scd_local->ctx = ctx;
403     }
404   if (!pth_mutex_release (&start_scd_lock))
405     log_error ("failed to release the start_scd lock: %s\n", strerror (errno));
406   return err;
407 }
408
409
410 /* Check whether the Scdaemon is still alive and clean it up if not. */
411 void
412 agent_scd_check_aliveness (void)
413 {
414   pth_event_t evt;
415   pid_t pid;
416 #ifdef HAVE_W32_SYSTEM
417   DWORD rc;
418 #else
419   int rc;
420 #endif
421
422   if (!primary_scd_ctx)
423     return; /* No scdaemon running. */
424
425   /* This is not a critical function so we use a short timeout while
426      acquiring the lock.  */
427   evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0));
428   if (!pth_mutex_acquire (&start_scd_lock, 0, evt))
429     {
430       if (pth_event_occurred (evt))
431         {
432           if (opt.verbose > 1)
433             log_info ("failed to acquire the start_scd lock while"
434                       " doing an aliveness check: %s\n", "timeout");
435         }
436       else
437         log_error ("failed to acquire the start_scd lock while"
438                    " doing an aliveness check: %s\n", strerror (errno));
439       pth_event_free (evt, PTH_FREE_THIS);
440       return;
441     }
442   pth_event_free (evt, PTH_FREE_THIS);
443
444   if (primary_scd_ctx)
445     {
446       pid = assuan_get_pid (primary_scd_ctx);
447 #ifdef HAVE_W32_SYSTEM
448       /* If we have a PID we disconnect if either GetExitProcessCode
449          fails or if ir returns the exit code of the scdaemon.  259 is
450          the error code for STILL_ALIVE.  */
451       if (pid != (pid_t)(void*)(-1) && pid
452           && (!GetExitCodeProcess ((HANDLE)pid, &rc) || rc != 259))
453 #else
454       if (pid != (pid_t)(-1) && pid
455           && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
456 #endif
457         {
458           /* Okay, scdaemon died.  Disconnect the primary connection
459              now but take care that it won't do another wait. Also
460              cleanup all other connections and release their
461              resources.  The next use will start a new daemon then.
462              Due to the use of the START_SCD_LOCAL we are sure that
463              none of these context are actually in use. */
464           struct scd_local_s *sl;
465
466           assuan_set_flag (primary_scd_ctx, ASSUAN_NO_WAITPID, 1);
467           assuan_disconnect (primary_scd_ctx);
468
469           for (sl=scd_local_list; sl; sl = sl->next_local)
470             {
471               if (sl->ctx)
472                 {
473                   if (sl->ctx != primary_scd_ctx)
474                     assuan_disconnect (sl->ctx);
475                   sl->ctx = NULL;
476                 }
477             }
478           
479           primary_scd_ctx = NULL;
480           primary_scd_ctx_reusable = 0;
481
482           xfree (socket_name);
483           socket_name = NULL;
484         }
485     }
486
487   if (!pth_mutex_release (&start_scd_lock))
488     log_error ("failed to release the start_scd lock while"
489                " doing the aliveness check: %s\n", strerror (errno));
490 }
491
492
493
494 /* Reset the SCD if it has been used.  Actually it is not a reset but
495    a cleanup of resources used by the current connection. */
496 int
497 agent_reset_scd (ctrl_t ctrl)
498 {
499   if (ctrl->scd_local)
500     {
501       if (ctrl->scd_local->ctx)
502         {
503           /* We can't disconnect the primary context because libassuan
504              does a waitpid on it and thus the system would hang.
505              Instead we send a reset and keep that connection for
506              reuse. */
507           if (ctrl->scd_local->ctx == primary_scd_ctx)
508             {
509               /* Send a RESTART to the SCD.  This is required for the
510                  primary connection as a kind of virtual EOF; we don't
511                  have another way to tell it that the next command
512                  should be viewed as if a new connection has been
513                  made.  For the non-primary connections this is not
514                  needed as we simply close the socket.  We don't check
515                  for an error here because the RESTART may fail for
516                  example if the scdaemon has already been terminated.
517                  Anyway, we need to set the reusable flag to make sure
518                  that the aliveness check can clean it up. */
519               assuan_transact (primary_scd_ctx, "RESTART",
520                                NULL, NULL, NULL, NULL, NULL, NULL);
521               primary_scd_ctx_reusable = 1;
522             }
523           else
524             assuan_disconnect (ctrl->scd_local->ctx);
525           ctrl->scd_local->ctx = NULL;
526         }
527       
528       /* Remove the local context from our list and release it. */
529       if (!scd_local_list)
530         BUG ();
531       else if (scd_local_list == ctrl->scd_local)
532         scd_local_list = ctrl->scd_local->next_local;
533       else
534         {
535           struct scd_local_s *sl;
536       
537           for (sl=scd_local_list; sl->next_local; sl = sl->next_local)
538             if (sl->next_local == ctrl->scd_local)
539               break;
540           if (!sl->next_local)
541             BUG ();
542           sl->next_local = ctrl->scd_local->next_local;
543         }
544       xfree (ctrl->scd_local);
545       ctrl->scd_local = NULL;
546     }
547
548   return 0;
549 }
550
551
552 \f
553 /* Return a new malloced string by unescaping the string S.  Escaping
554    is percent escaping and '+'/space mapping.  A binary Nul will
555    silently be replaced by a 0xFF.  Function returns NULL to indicate
556    an out of memory status. */
557 static char *
558 unescape_status_string (const unsigned char *s)
559 {
560   char *buffer, *d;
561
562   buffer = d = xtrymalloc (strlen ((const char*)s)+1);
563   if (!buffer)
564     return NULL;
565   while (*s)
566     {
567       if (*s == '%' && s[1] && s[2])
568         { 
569           s++;
570           *d = xtoi_2 (s);
571           if (!*d)
572             *d = '\xff';
573           d++;
574           s += 2;
575         }
576       else if (*s == '+')
577         {
578           *d++ = ' ';
579           s++;
580         }
581       else
582         *d++ = *s++;
583     }
584   *d = 0; 
585   return buffer;
586 }
587
588
589 \f
590 static int
591 learn_status_cb (void *opaque, const char *line)
592 {
593   struct learn_parm_s *parm = opaque;
594   const char *keyword = line;
595   int keywordlen;
596
597   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
598     ;
599   while (spacep (line))
600     line++;
601   if (keywordlen == 8 && !memcmp (keyword, "CERTINFO", keywordlen))
602     {
603       parm->certinfo_cb (parm->certinfo_cb_arg, line);
604     }
605   else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
606     {
607       parm->kpinfo_cb (parm->kpinfo_cb_arg, line);
608     }
609   else if (keywordlen && *line)
610     {
611       parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
612     }
613   
614   return 0;
615 }
616
617 /* Perform the LEARN command and return a list of all private keys
618    stored on the card. */
619 int
620 agent_card_learn (ctrl_t ctrl,
621                   void (*kpinfo_cb)(void*, const char *),
622                   void *kpinfo_cb_arg,
623                   void (*certinfo_cb)(void*, const char *),
624                   void *certinfo_cb_arg,
625                   void (*sinfo_cb)(void*, const char *, size_t, const char *),
626                   void *sinfo_cb_arg)
627 {
628   int rc;
629   struct learn_parm_s parm;
630
631   rc = start_scd (ctrl);
632   if (rc)
633     return rc;
634
635   memset (&parm, 0, sizeof parm);
636   parm.kpinfo_cb = kpinfo_cb;
637   parm.kpinfo_cb_arg = kpinfo_cb_arg;
638   parm.certinfo_cb = certinfo_cb;
639   parm.certinfo_cb_arg = certinfo_cb_arg;
640   parm.sinfo_cb = sinfo_cb;
641   parm.sinfo_cb_arg = sinfo_cb_arg;
642   rc = assuan_transact (ctrl->scd_local->ctx, "LEARN --force",
643                         NULL, NULL, NULL, NULL,
644                         learn_status_cb, &parm);
645   if (rc)
646     return unlock_scd (ctrl, rc);
647
648   return unlock_scd (ctrl, 0);
649 }
650
651
652 \f
653 static int
654 get_serialno_cb (void *opaque, const char *line)
655 {
656   char **serialno = opaque;
657   const char *keyword = line;
658   const char *s;
659   int keywordlen, n;
660
661   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
662     ;
663   while (spacep (line))
664     line++;
665
666   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
667     {
668       if (*serialno)
669         return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
670       for (n=0,s=line; hexdigitp (s); s++, n++)
671         ;
672       if (!n || (n&1)|| !(spacep (s) || !*s) )
673         return gpg_error (GPG_ERR_ASS_PARAMETER);
674       *serialno = xtrymalloc (n+1);
675       if (!*serialno)
676         return out_of_core ();
677       memcpy (*serialno, line, n);
678       (*serialno)[n] = 0;
679     }
680   
681   return 0;
682 }
683
684 /* Return the serial number of the card or an appropriate error.  The
685    serial number is returned as a hexstring. */
686 int
687 agent_card_serialno (ctrl_t ctrl, char **r_serialno)
688 {
689   int rc;
690   char *serialno = NULL;
691
692   rc = start_scd (ctrl);
693   if (rc)
694     return rc;
695
696   rc = assuan_transact (ctrl->scd_local->ctx, "SERIALNO",
697                         NULL, NULL, NULL, NULL,
698                         get_serialno_cb, &serialno);
699   if (rc)
700     {
701       xfree (serialno);
702       return unlock_scd (ctrl, rc);
703     }
704   *r_serialno = serialno;
705   return unlock_scd (ctrl, 0);
706 }
707
708
709
710 \f
711 static int
712 membuf_data_cb (void *opaque, const void *buffer, size_t length)
713 {
714   membuf_t *data = opaque;
715
716   if (buffer)
717     put_membuf (data, buffer, length);
718   return 0;
719 }
720   
721 /* Handle the NEEDPIN inquiry. */
722 static int
723 inq_needpin (void *opaque, const char *line)
724 {
725   struct inq_needpin_s *parm = opaque;
726   char *pin;
727   size_t pinlen;
728   int rc;
729
730   if (!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7]))
731     {
732       line += 7;
733       while (*line == ' ')
734         line++;
735       
736       pinlen = 90;
737       pin = gcry_malloc_secure (pinlen);
738       if (!pin)
739         return out_of_core ();
740
741       rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen);
742       if (!rc)
743         rc = assuan_send_data (parm->ctx, pin, pinlen);
744       xfree (pin);
745     }
746   else if (!strncmp (line, "POPUPKEYPADPROMPT", 17)
747            && (line[17] == ' ' || !line[17]))
748     {
749       line += 17;
750       while (*line == ' ')
751         line++;
752       
753       rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, 1);
754     }
755   else if (!strncmp (line, "DISMISSKEYPADPROMPT", 19)
756            && (line[19] == ' ' || !line[19]))
757     {
758       rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0);
759     }
760   else if (parm->passthru)
761     {
762       unsigned char *value;
763       size_t valuelen;
764       int rest;
765       int needrest = !strncmp (line, "KEYDATA", 8);
766
767       /* Pass the inquiry up to our caller.  We limit the maximum
768          amount to an arbitrary value.  As we know that the KEYDATA
769          enquiry is pretty sensitive we disable logging then */
770       if ((rest = (needrest
771                    && !assuan_get_flag (parm->passthru, ASSUAN_CONFIDENTIAL))))
772         assuan_begin_confidential (parm->passthru);
773       rc = assuan_inquire (parm->passthru, line, &value, &valuelen, 8096);
774       if (rest)
775         assuan_end_confidential (parm->passthru);
776       if (!rc)
777         {
778           if ((rest = (needrest 
779                        && !assuan_get_flag (parm->ctx, ASSUAN_CONFIDENTIAL))))
780             assuan_begin_confidential (parm->ctx);
781           rc = assuan_send_data (parm->ctx, value, valuelen);
782           if (rest)
783             assuan_end_confidential (parm->ctx);
784           xfree (value);
785         }
786       else
787         log_error ("error forwarding inquiry `%s': %s\n", 
788                    line, gpg_strerror (rc));
789     }
790   else
791     {
792       log_error ("unsupported inquiry `%s'\n", line);
793       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
794     }
795
796   return rc;
797 }
798
799
800
801 /* Create a signature using the current card */
802 int
803 agent_card_pksign (ctrl_t ctrl,
804                    const char *keyid,
805                    int (*getpin_cb)(void *, const char *, char*, size_t),
806                    void *getpin_cb_arg,
807                    const unsigned char *indata, size_t indatalen,
808                    unsigned char **r_buf, size_t *r_buflen)
809 {
810   int rc, i;
811   char *p, line[ASSUAN_LINELENGTH];
812   membuf_t data;
813   struct inq_needpin_s inqparm;
814   size_t len;
815   unsigned char *sigbuf;
816   size_t sigbuflen;
817
818   *r_buf = NULL;
819   rc = start_scd (ctrl);
820   if (rc)
821     return rc;
822
823   if (indatalen*2 + 50 > DIM(line))
824     return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
825
826   sprintf (line, "SETDATA ");
827   p = line + strlen (line);
828   for (i=0; i < indatalen ; i++, p += 2 )
829     sprintf (p, "%02X", indata[i]);
830   rc = assuan_transact (ctrl->scd_local->ctx, line,
831                         NULL, NULL, NULL, NULL, NULL, NULL);
832   if (rc)
833     return unlock_scd (ctrl, rc);
834
835   init_membuf (&data, 1024);
836   inqparm.ctx = ctrl->scd_local->ctx;
837   inqparm.getpin_cb = getpin_cb;
838   inqparm.getpin_cb_arg = getpin_cb_arg;
839   inqparm.passthru = 0;
840   snprintf (line, DIM(line)-1, 
841             ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid);
842   line[DIM(line)-1] = 0;
843   rc = assuan_transact (ctrl->scd_local->ctx, line,
844                         membuf_data_cb, &data,
845                         inq_needpin, &inqparm,
846                         NULL, NULL);
847   if (rc)
848     {
849       xfree (get_membuf (&data, &len));
850       return unlock_scd (ctrl, rc);
851     }
852   sigbuf = get_membuf (&data, &sigbuflen);
853
854   /* Create an S-expression from it which is formatted like this:
855      "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */
856   *r_buflen = 21 + 11 + sigbuflen + 4;
857   p = xtrymalloc (*r_buflen);
858   *r_buf = (unsigned char*)p;
859   if (!p)
860     return unlock_scd (ctrl, out_of_core ());
861   p = stpcpy (p, "(7:sig-val(3:rsa(1:s" );
862   sprintf (p, "%u:", (unsigned int)sigbuflen);
863   p += strlen (p);
864   memcpy (p, sigbuf, sigbuflen);
865   p += sigbuflen;
866   strcpy (p, ")))");
867   xfree (sigbuf);
868
869   assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
870   return unlock_scd (ctrl, 0);
871 }
872
873 /* Decipher INDATA using the current card. Note that the returned value is */
874 int
875 agent_card_pkdecrypt (ctrl_t ctrl,
876                       const char *keyid,
877                       int (*getpin_cb)(void *, const char *, char*, size_t),
878                       void *getpin_cb_arg,
879                       const unsigned char *indata, size_t indatalen,
880                       char **r_buf, size_t *r_buflen)
881 {
882   int rc, i;
883   char *p, line[ASSUAN_LINELENGTH];
884   membuf_t data;
885   struct inq_needpin_s inqparm;
886   size_t len;
887
888   *r_buf = NULL;
889   rc = start_scd (ctrl);
890   if (rc)
891     return rc;
892
893   /* FIXME: use secure memory where appropriate */
894   if (indatalen*2 + 50 > DIM(line))
895     return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
896
897   sprintf (line, "SETDATA ");
898   p = line + strlen (line);
899   for (i=0; i < indatalen ; i++, p += 2 )
900     sprintf (p, "%02X", indata[i]);
901   rc = assuan_transact (ctrl->scd_local->ctx, line,
902                         NULL, NULL, NULL, NULL, NULL, NULL);
903   if (rc)
904     return unlock_scd (ctrl, rc);
905
906   init_membuf (&data, 1024);
907   inqparm.ctx = ctrl->scd_local->ctx;
908   inqparm.getpin_cb = getpin_cb;
909   inqparm.getpin_cb_arg = getpin_cb_arg;
910   inqparm.passthru = 0;
911   snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
912   line[DIM(line)-1] = 0;
913   rc = assuan_transact (ctrl->scd_local->ctx, line,
914                         membuf_data_cb, &data,
915                         inq_needpin, &inqparm,
916                         NULL, NULL);
917   if (rc)
918     {
919       xfree (get_membuf (&data, &len));
920       return unlock_scd (ctrl, rc);
921     }
922   *r_buf = get_membuf (&data, r_buflen);
923   if (!*r_buf)
924     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
925
926   return unlock_scd (ctrl, 0);
927 }
928
929
930 \f
931 /* Read a certificate with ID into R_BUF and R_BUFLEN. */
932 int
933 agent_card_readcert (ctrl_t ctrl,
934                      const char *id, char **r_buf, size_t *r_buflen)
935 {
936   int rc;
937   char line[ASSUAN_LINELENGTH];
938   membuf_t data;
939   size_t len;
940
941   *r_buf = NULL;
942   rc = start_scd (ctrl);
943   if (rc)
944     return rc;
945
946   init_membuf (&data, 1024);
947   snprintf (line, DIM(line)-1, "READCERT %s", id);
948   line[DIM(line)-1] = 0;
949   rc = assuan_transact (ctrl->scd_local->ctx, line,
950                         membuf_data_cb, &data,
951                         NULL, NULL,
952                         NULL, NULL);
953   if (rc)
954     {
955       xfree (get_membuf (&data, &len));
956       return unlock_scd (ctrl, rc);
957     }
958   *r_buf = get_membuf (&data, r_buflen);
959   if (!*r_buf)
960     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
961
962   return unlock_scd (ctrl, 0);
963 }
964
965
966 \f
967 /* Read a key with ID and return it in an allocate buffer pointed to
968    by r_BUF as a valid S-expression. */
969 int
970 agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
971 {
972   int rc;
973   char line[ASSUAN_LINELENGTH];
974   membuf_t data;
975   size_t len, buflen;
976
977   *r_buf = NULL;
978   rc = start_scd (ctrl);
979   if (rc)
980     return rc;
981
982   init_membuf (&data, 1024);
983   snprintf (line, DIM(line)-1, "READKEY %s", id);
984   line[DIM(line)-1] = 0;
985   rc = assuan_transact (ctrl->scd_local->ctx, line,
986                         membuf_data_cb, &data,
987                         NULL, NULL,
988                         NULL, NULL);
989   if (rc)
990     {
991       xfree (get_membuf (&data, &len));
992       return unlock_scd (ctrl, rc);
993     }
994   *r_buf = get_membuf (&data, &buflen);
995   if (!*r_buf)
996     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
997
998   if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL))
999     {
1000       xfree (*r_buf); *r_buf = NULL;
1001       return unlock_scd (ctrl, gpg_error (GPG_ERR_INV_VALUE));
1002     }
1003
1004   return unlock_scd (ctrl, 0);
1005 }
1006
1007
1008 \f
1009 /* Type used with the card_getattr_cb.  */
1010 struct card_getattr_parm_s {
1011   const char *keyword;  /* Keyword to look for.  */
1012   size_t keywordlen;    /* strlen of KEYWORD.  */
1013   char *data;           /* Malloced and unescaped data.  */
1014   int error;            /* ERRNO value or 0 on success. */
1015 };
1016
1017 /* Callback function for agent_card_getattr.  */
1018 static assuan_error_t
1019 card_getattr_cb (void *opaque, const char *line)
1020 {
1021   struct card_getattr_parm_s *parm = opaque;
1022   const char *keyword = line;
1023   int keywordlen;
1024
1025   if (parm->data)
1026     return 0; /* We want only the first occurrence.  */
1027
1028   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1029     ;
1030   while (spacep (line))
1031     line++;
1032
1033   if (keywordlen == parm->keywordlen
1034       && !memcmp (keyword, parm->keyword, keywordlen))
1035     {
1036       parm->data = unescape_status_string ((const unsigned char*)line);
1037       if (!parm->data)
1038         parm->error = errno;
1039     }
1040   
1041   return 0;
1042 }
1043
1044
1045 /* Call the agent to retrieve a single line data object. On success
1046    the object is malloced and stored at RESULT; it is guaranteed that
1047    NULL is never stored in this case.  On error an error code is
1048    returned and NULL stored at RESULT. */
1049 gpg_error_t
1050 agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
1051 {
1052   int err;
1053   struct card_getattr_parm_s parm;
1054   char line[ASSUAN_LINELENGTH];
1055
1056   *result = NULL;
1057
1058   if (!*name)
1059     return gpg_error (GPG_ERR_INV_VALUE);
1060
1061   memset (&parm, 0, sizeof parm);
1062   parm.keyword = name;
1063   parm.keywordlen = strlen (name);
1064
1065   /* We assume that NAME does not need escaping. */
1066   if (8 + strlen (name) > DIM(line)-1)
1067     return gpg_error (GPG_ERR_TOO_LARGE);
1068   stpcpy (stpcpy (line, "GETATTR "), name); 
1069
1070   err = start_scd (ctrl);
1071   if (err)
1072     return err;
1073
1074   err = assuan_transact (ctrl->scd_local->ctx, line,
1075                          NULL, NULL, NULL, NULL,
1076                          card_getattr_cb, &parm);
1077   if (!err && parm.error)
1078     err = gpg_error_from_errno (parm.error);
1079   
1080   if (!err && !parm.data)
1081     err = gpg_error (GPG_ERR_NO_DATA);
1082   
1083   if (!err)
1084     *result = parm.data;
1085   else
1086     xfree (parm.data);
1087
1088   return unlock_scd (ctrl, err);
1089 }
1090
1091
1092
1093 \f
1094 static int
1095 pass_status_thru (void *opaque, const char *line)
1096 {
1097   assuan_context_t ctx = opaque;
1098   char keyword[200];
1099   int i;
1100
1101   for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
1102     keyword[i] = *line;
1103   keyword[i] = 0;
1104   /* truncate any remaining keyword stuff. */
1105   for (; *line && !spacep (line); line++)
1106     ;
1107   while (spacep (line))
1108     line++;
1109
1110   assuan_write_status (ctx, keyword, line);
1111   return 0;
1112 }
1113
1114 static int
1115 pass_data_thru (void *opaque, const void *buffer, size_t length)
1116 {
1117   assuan_context_t ctx = opaque;
1118
1119   assuan_send_data (ctx, buffer, length);
1120   return 0;
1121 }
1122
1123
1124 /* Send the line CMDLINE with command for the SCDdaemon to it and send
1125    all status messages back.  This command is used as a general quoting
1126    mechanism to pass everything verbatim to SCDAEMON.  The PIN
1127    inquiry is handled inside gpg-agent.  */
1128 int
1129 agent_card_scd (ctrl_t ctrl, const char *cmdline,
1130                 int (*getpin_cb)(void *, const char *, char*, size_t),
1131                 void *getpin_cb_arg, void *assuan_context)
1132 {
1133   int rc;
1134   struct inq_needpin_s inqparm;
1135
1136   rc = start_scd (ctrl);
1137   if (rc)
1138     return rc;
1139
1140   inqparm.ctx = ctrl->scd_local->ctx;
1141   inqparm.getpin_cb = getpin_cb;
1142   inqparm.getpin_cb_arg = getpin_cb_arg;
1143   inqparm.passthru = assuan_context;
1144   rc = assuan_transact (ctrl->scd_local->ctx, cmdline,
1145                         pass_data_thru, assuan_context,
1146                         inq_needpin, &inqparm,
1147                         pass_status_thru, assuan_context);
1148   if (rc)
1149     {
1150       return unlock_scd (ctrl, rc);
1151     }
1152
1153   return unlock_scd (ctrl, 0);
1154 }
1155
1156