dirmngr: Don't add system CAs for SKS HKPS pool.
[gnupg.git] / scd / command.c
1 /* command.c - SCdaemon command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3  *               2007, 2008, 2009, 2011  Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <https://www.gnu.org/licenses/>.
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 <unistd.h>
28 #include <signal.h>
29 #ifdef USE_NPTH
30 # include <npth.h>
31 #endif
32
33 #include "scdaemon.h"
34 #include <assuan.h>
35 #include <ksba.h>
36 #include "iso7816.h"
37 #include "apdu.h" /* Required for apdu_*_reader (). */
38 #include "atr.h"
39 #ifdef HAVE_LIBUSB
40 #include "ccid-driver.h"
41 #endif
42 #include "../common/asshelp.h"
43 #include "../common/server-help.h"
44
45 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
46 #define MAXLEN_PIN 100
47
48 /* Maximum allowed size of key data as used in inquiries. */
49 #define MAXLEN_KEYDATA 4096
50
51 /* Maximum allowed total data size for SETDATA.  */
52 #define MAXLEN_SETDATA 4096
53
54 /* Maximum allowed size of certificate data as used in inquiries. */
55 #define MAXLEN_CERTDATA 16384
56
57 /* Maximum allowed size for "SETATTR --inquire". */
58 #define MAXLEN_SETATTRDATA 16384
59
60
61 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
62
63 #define IS_LOCKED(c) (locked_session && locked_session != (c)->server_local)
64
65
66 /* Data used to associate an Assuan context with local server data.
67    This object describes the local properties of one session.  */
68 struct server_local_s
69 {
70   /* We keep a list of all active sessions with the anchor at
71      SESSION_LIST (see below).  This field is used for linking. */
72   struct server_local_s *next_session;
73
74   /* This object is usually assigned to a CTRL object (which is
75      globally visible).  While enumerating all sessions we sometimes
76      need to access data of the CTRL object; thus we keep a
77      backpointer here. */
78   ctrl_t ctrl_backlink;
79
80   /* The Assuan context used by this session/server. */
81   assuan_context_t assuan_ctx;
82
83 #ifdef HAVE_W32_SYSTEM
84   void *event_signal;           /* Or NULL if not used. */
85 #else
86   int event_signal;             /* Or 0 if not used. */
87 #endif
88
89   /* True if the card has been removed and a reset is required to
90      continue operation. */
91   int card_removed;
92
93   /* If set to true we will be terminate ourself at the end of the
94      this session.  */
95   int stopme;
96
97 };
98
99
100 /* To keep track of all running sessions, we link all active server
101    contexts and the anchor in this variable.  */
102 static struct server_local_s *session_list;
103
104 /* If a session has been locked we store a link to its server object
105    in this variable. */
106 static struct server_local_s *locked_session;
107
108 \f
109 /* Convert the STRING into a newly allocated buffer while translating
110    the hex numbers.  Stops at the first invalid character.  Blanks and
111    colons are allowed to separate the hex digits.  Returns NULL on
112    error or a newly malloced buffer and its length in LENGTH.  */
113 static unsigned char *
114 hex_to_buffer (const char *string, size_t *r_length)
115 {
116   unsigned char *buffer;
117   const char *s;
118   size_t n;
119
120   buffer = xtrymalloc (strlen (string)+1);
121   if (!buffer)
122     return NULL;
123   for (s=string, n=0; *s; s++)
124     {
125       if (spacep (s) || *s == ':')
126         continue;
127       if (hexdigitp (s) && hexdigitp (s+1))
128         {
129           buffer[n++] = xtoi_2 (s);
130           s++;
131         }
132       else
133         break;
134     }
135   *r_length = n;
136   return buffer;
137 }
138
139
140
141 /* Reset the card and free the application context.  With SEND_RESET
142    set to true actually send a RESET to the reader; this is the normal
143    way of calling the function.  */
144 static void
145 do_reset (ctrl_t ctrl, int send_reset)
146 {
147   card_t card = ctrl->card_ctx;
148
149   if (card)
150     card_reset (card, ctrl, IS_LOCKED (ctrl)? 0: send_reset);
151
152   /* If we hold a lock, unlock now. */
153   if (locked_session && ctrl->server_local == locked_session)
154     {
155       locked_session = NULL;
156       log_info ("implicitly unlocking due to RESET\n");
157     }
158 }
159
160
161 \f
162 static gpg_error_t
163 reset_notify (assuan_context_t ctx, char *line)
164 {
165   ctrl_t ctrl = assuan_get_pointer (ctx);
166
167   (void) line;
168
169   do_reset (ctrl, 1);
170   return 0;
171 }
172
173
174 static gpg_error_t
175 option_handler (assuan_context_t ctx, const char *key, const char *value)
176 {
177   ctrl_t ctrl = assuan_get_pointer (ctx);
178
179   if (!strcmp (key, "event-signal"))
180     {
181       /* A value of 0 is allowed to reset the event signal. */
182 #ifdef HAVE_W32_SYSTEM
183       if (!*value)
184         return gpg_error (GPG_ERR_ASS_PARAMETER);
185 #ifdef _WIN64
186       ctrl->server_local->event_signal = (void *)strtoull (value, NULL, 16);
187 #else
188       ctrl->server_local->event_signal = (void *)strtoul (value, NULL, 16);
189 #endif
190 #else
191       int i = *value? atoi (value) : -1;
192       if (i < 0)
193         return gpg_error (GPG_ERR_ASS_PARAMETER);
194       ctrl->server_local->event_signal = i;
195 #endif
196     }
197
198  return 0;
199 }
200
201
202 /* If the card has not yet been opened, do it.  */
203 static gpg_error_t
204 open_card (ctrl_t ctrl)
205 {
206   /* If we ever got a card not present error code, return that.  Only
207      the SERIALNO command and a reset are able to clear from that
208      state. */
209   if (ctrl->server_local->card_removed)
210     return gpg_error (GPG_ERR_CARD_REMOVED);
211
212   if ( IS_LOCKED (ctrl) )
213     return gpg_error (GPG_ERR_LOCKED);
214
215   if (ctrl->card_ctx)
216     return 0;
217
218   return select_application (ctrl, NULL, &ctrl->card_ctx, 0, NULL, 0);
219 }
220
221 /* Explicitly open a card for a specific use of APPTYPE or SERIALNO.  */
222 static gpg_error_t
223 open_card_with_request (ctrl_t ctrl,
224                         const char *apptypestr, const char *serialno)
225 {
226   gpg_error_t err;
227   unsigned char *serialno_bin = NULL;
228   size_t serialno_bin_len = 0;
229   card_t card = ctrl->card_ctx;
230
231   if (serialno)
232     serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
233
234   /* If we are already initialized for one specific application we
235      need to check that the client didn't requested a specific
236      application different from the one in use before we continue. */
237   if (apptypestr && ctrl->card_ctx)
238     {
239       err = check_application_conflict (ctrl->card_ctx, apptypestr,
240                                         serialno_bin, serialno_bin_len);
241       if (gpg_err_code (err) == GPG_ERR_FALSE)
242         {
243           /* Different application but switching is supported.  */
244           err = select_additional_application (ctrl, apptypestr);
245         }
246       goto leave;
247     }
248
249   /* Re-scan USB devices.  Release CARD, before the scan.  */
250   /* FIXME: Is a card_unref sufficient or do we need to deallocate?  */
251   ctrl->card_ctx = NULL;
252   card_unref (card);
253
254   err = select_application (ctrl, apptypestr, &ctrl->card_ctx, 1,
255                             serialno_bin, serialno_bin_len);
256
257  leave:
258   xfree (serialno_bin);
259   return err;
260 }
261
262
263 static const char hlp_serialno[] =
264   "SERIALNO [--demand=<serialno>] [<apptype>]\n"
265   "\n"
266   "Return the serial number of the card using a status response.  This\n"
267   "function should be used to check for the presence of a card.\n"
268   "\n"
269   "If --demand is given, an application on the card with SERIALNO is\n"
270   "selected and an error is returned if no such card available.\n"
271   "\n"
272   "If APPTYPE is given, an application of that type is selected and an\n"
273   "error is returned if the application is not supported or available.\n"
274   "The default is to auto-select the application using a hardwired\n"
275   "preference system.  Note, that a future extension to this function\n"
276   "may enable specifying a list and order of applications to try.\n"
277   "\n"
278   "This function is special in that it can be used to reset the card.\n"
279   "Most other functions will return an error when a card change has\n"
280   "been detected and the use of this function is therefore required.\n"
281   "\n"
282   "Background: We want to keep the client clear of handling card\n"
283   "changes between operations; i.e. the client can assume that all\n"
284   "operations are done on the same card unless he calls this function.";
285 static gpg_error_t
286 cmd_serialno (assuan_context_t ctx, char *line)
287 {
288   ctrl_t ctrl = assuan_get_pointer (ctx);
289   struct server_local_s *sl;
290   int rc = 0;
291   char *serial;
292   const char *demand;
293
294   if ( IS_LOCKED (ctrl) )
295     return gpg_error (GPG_ERR_LOCKED);
296
297   if ((demand = has_option_name (line, "--demand")))
298     {
299       if (*demand != '=')
300         return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
301       line = (char *)++demand;
302       for (; *line && !spacep (line); line++)
303         ;
304       if (*line)
305         *line++ = 0;
306     }
307   else
308     demand = NULL;
309
310   /* Clear the remove flag so that the open_card is able to reread it.  */
311   if (ctrl->server_local->card_removed)
312     ctrl->server_local->card_removed = 0;
313
314   if ((rc = open_card_with_request (ctrl, *line? line:NULL, demand)))
315     {
316       ctrl->server_local->card_removed = 1;
317       return rc;
318     }
319
320   /* Success, clear the card_removed flag for all sessions.  */
321   for (sl=session_list; sl; sl = sl->next_session)
322     {
323       ctrl_t c = sl->ctrl_backlink;
324
325       if (c != ctrl)
326         c->server_local->card_removed = 0;
327     }
328
329   serial = card_get_serialno (ctrl->card_ctx);
330   if (!serial)
331     return gpg_error (GPG_ERR_INV_VALUE);
332
333   rc = assuan_write_status (ctx, "SERIALNO", serial);
334   xfree (serial);
335   return rc;
336 }
337
338
339 static const char hlp_learn[] =
340   "LEARN [--force] [--keypairinfo]\n"
341   "\n"
342   "Learn all useful information of the currently inserted card.  When\n"
343   "used without the force options, the command might do an INQUIRE\n"
344   "like this:\n"
345   "\n"
346   "   INQUIRE KNOWNCARDP <hexstring_with_serialNumber>\n"
347   "\n"
348   "The client should just send an \"END\" if the processing should go on\n"
349   "or a \"CANCEL\" to force the function to terminate with a Cancel\n"
350   "error message.\n"
351   "\n"
352   "With the option --keypairinfo only KEYPARIINFO status lines are\n"
353   "returned.\n"
354   "\n"
355   "The response of this command is a list of status lines formatted as\n"
356   "this:\n"
357   "\n"
358   "  S APPTYPE <apptype>\n"
359   "\n"
360   "This returns the type of the application, currently the strings:\n"
361   "\n"
362   "    P15     = PKCS-15 structure used\n"
363   "    DINSIG  = DIN SIG\n"
364   "    OPENPGP = OpenPGP card\n"
365   "    PIV     = PIV card\n"
366   "    NKS     = NetKey card\n"
367   "\n"
368   "are implemented.  These strings are aliases for the AID\n"
369   "\n"
370   "  S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id> [<usage>]\n"
371   "\n"
372   "If there is no certificate yet stored on the card a single 'X' is\n"
373   "returned as the keygrip.  In addition to the keypair info, information\n"
374   "about all certificates stored on the card is also returned:\n"
375   "\n"
376   "  S CERTINFO <certtype> <hexstring_with_id>\n"
377   "\n"
378   "Where CERTTYPE is a number indicating the type of certificate:\n"
379   "   0   := Unknown\n"
380   "   100 := Regular X.509 cert\n"
381   "   101 := Trusted X.509 cert\n"
382   "   102 := Useful X.509 cert\n"
383   "   110 := Root CA cert in a special format (e.g. DINSIG)\n"
384   "   111 := Root CA cert as standard X509 cert.\n"
385   "\n"
386   "For certain cards, more information will be returned:\n"
387   "\n"
388   "  S KEY-FPR <no> <hexstring>\n"
389   "\n"
390   "For OpenPGP cards this returns the stored fingerprints of the\n"
391   "keys. This can be used check whether a key is available on the\n"
392   "card.  NO may be 1, 2 or 3.\n"
393   "\n"
394   "  S CA-FPR <no> <hexstring>\n"
395   "\n"
396   "Similar to above, these are the fingerprints of keys assumed to be\n"
397   "ultimately trusted.\n"
398   "\n"
399   "  S DISP-NAME <name_of_card_holder>\n"
400   "\n"
401   "The name of the card holder as stored on the card; percent\n"
402   "escaping takes place, spaces are encoded as '+'\n"
403   "\n"
404   "  S PUBKEY-URL <url>\n"
405   "\n"
406   "The URL to be used for locating the entire public key.\n"
407   "  \n"
408   "Note, that this function may even be used on a locked card.";
409 static gpg_error_t
410 cmd_learn (assuan_context_t ctx, char *line)
411 {
412   ctrl_t ctrl = assuan_get_pointer (ctx);
413   int rc = 0;
414   int only_keypairinfo = has_option (line, "--keypairinfo");
415
416   if ((rc = open_card (ctrl)))
417     return rc;
418
419   /* Unless the force option is used we try a shortcut by identifying
420      the card using a serial number and inquiring the client with
421      that. The client may choose to cancel the operation if he already
422      knows about this card */
423   if (!only_keypairinfo)
424     {
425       const char *reader;
426       char *serial;
427       card_t card = ctrl->card_ctx;
428
429       if (!card)
430         return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
431
432       reader = apdu_get_reader_name (card->slot);
433       if (!reader)
434         return out_of_core ();
435       send_status_direct (ctrl, "READER", reader);
436       /* No need to free the string of READER.  */
437
438       serial = card_get_serialno (ctrl->card_ctx);
439       if (!serial)
440         return gpg_error (GPG_ERR_INV_VALUE);
441
442       rc = assuan_write_status (ctx, "SERIALNO", serial);
443       if (rc < 0)
444         {
445           xfree (serial);
446           return out_of_core ();
447         }
448
449       if (!has_option (line, "--force"))
450         {
451           char *command;
452
453           rc = gpgrt_asprintf (&command, "KNOWNCARDP %s", serial);
454           if (rc < 0)
455             {
456               xfree (serial);
457               return out_of_core ();
458             }
459           rc = assuan_inquire (ctx, command, NULL, NULL, 0);
460           xfree (command);
461           if (rc)
462             {
463               if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
464                 log_error ("inquire KNOWNCARDP failed: %s\n",
465                            gpg_strerror (rc));
466               xfree (serial);
467               return rc;
468             }
469           /* Not canceled, so we have to proceed.  */
470         }
471       xfree (serial);
472     }
473
474   /* Let the application print out its collection of useful status
475      information. */
476   if (!rc)
477     rc = app_write_learn_status (ctrl->card_ctx, ctrl, only_keypairinfo);
478
479   return rc;
480 }
481
482
483 \f
484 static const char hlp_readcert[] =
485   "READCERT <hexified_certid>|<keyid>|<oid>\n"
486   "\n"
487   "Note, that this function may even be used on a locked card.";
488 static gpg_error_t
489 cmd_readcert (assuan_context_t ctx, char *line)
490 {
491   ctrl_t ctrl = assuan_get_pointer (ctx);
492   int rc;
493   unsigned char *cert;
494   size_t ncert;
495
496   if ((rc = open_card (ctrl)))
497     return rc;
498
499   line = xstrdup (line); /* Need a copy of the line. */
500   rc = app_readcert (ctrl->card_ctx, ctrl, line, &cert, &ncert);
501   if (rc)
502     log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
503   xfree (line);
504   line = NULL;
505   if (!rc)
506     {
507       rc = assuan_send_data (ctx, cert, ncert);
508       xfree (cert);
509       if (rc)
510         return rc;
511     }
512
513   return rc;
514 }
515
516
517 static const char hlp_readkey[] =
518   "READKEY [--advanced] [--info[-only]] <keyid>|<oid>\n"
519   "\n"
520   "Return the public key for the given cert or key ID as a standard\n"
521   "S-expression.  With --advanced  the S-expression is returned in\n"
522   "advanced format.  With --info a KEYPAIRINFO status line is also\n"
523   "emitted; with --info-only the regular output is suppressed.";
524 static gpg_error_t
525 cmd_readkey (assuan_context_t ctx, char *line)
526 {
527   ctrl_t ctrl = assuan_get_pointer (ctx);
528   int rc;
529   int advanced = 0;
530   int opt_info = 0;
531   int opt_nokey = 0;
532   unsigned char *cert = NULL;
533   unsigned char *pk = NULL;
534   size_t ncert, pklen;
535
536   if ((rc = open_card (ctrl)))
537     return rc;
538
539   if (has_option (line, "--advanced"))
540     advanced = 1;
541   if (has_option (line, "--info"))
542     opt_info = 1;
543   if (has_option (line, "--info-only"))
544     opt_info = opt_nokey = 1;
545
546   line = skip_options (line);
547   line = xstrdup (line); /* Need a copy of the line. */
548
549   /* If the application supports the READKEY function we use that.
550      Otherwise we use the old way by extracting it from the
551      certificate.  */
552   rc = app_readkey (ctrl->card_ctx, ctrl, line,
553                     opt_info? APP_READKEY_FLAG_INFO : 0,
554                     opt_nokey? NULL : &pk, &pklen);
555   if (!rc)
556     ; /* Okay, got that key.  */
557   else if (gpg_err_code (rc) == GPG_ERR_UNSUPPORTED_OPERATION
558            || gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
559     {
560       /* Fall back to certificate reading.  */
561       rc = app_readcert (ctrl->card_ctx, ctrl, line, &cert, &ncert);
562       if (rc)
563         {
564           log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
565           goto leave;
566         }
567       rc = app_help_pubkey_from_cert (cert, ncert, &pk, &pklen);
568       if (rc)
569         {
570           log_error ("failed to parse the certificate: %s\n",
571                      gpg_strerror (rc));
572           goto leave;
573         }
574
575       if (opt_info)
576         {
577           char keygripstr[KEYGRIP_LEN*2+1];
578
579           rc = app_help_get_keygrip_string_pk (pk, pklen, keygripstr);
580           if (rc)
581             {
582               log_error ("app_help_get_keygrip_string failed: %s\n",
583                          gpg_strerror (rc));
584               goto leave;
585             }
586
587           /* FIXME: Using LINE is not correct because it might be an
588            * OID and has not been canonicalized (i.e. uppercased).  */
589           send_status_info (ctrl, "KEYPAIRINFO",
590                             keygripstr, strlen (keygripstr),
591                             line, strlen (line),
592                             NULL, (size_t)0);
593         }
594     }
595   else
596     {
597       log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
598       goto leave;
599     }
600
601   if (opt_nokey)
602     ;
603   else if (advanced)
604     {
605       gcry_sexp_t s_key;
606       unsigned char *pkadv;
607       size_t pkadvlen;
608
609       rc = gcry_sexp_new (&s_key, pk, pklen, 0);
610       if (rc)
611         goto leave;
612
613       pkadvlen = gcry_sexp_sprint (s_key, GCRYSEXP_FMT_ADVANCED, NULL, 0);
614       pkadv = xtrymalloc (pkadvlen);
615       if (!pkadv)
616         {
617           rc = gpg_error_from_syserror ();
618           goto leave;
619         }
620       log_assert (pkadvlen);
621
622       gcry_sexp_sprint (s_key, GCRYSEXP_FMT_ADVANCED, pkadv, pkadvlen);
623       gcry_sexp_release (s_key);
624       /* (One less to adjust for the trailing '\0') */
625       rc = assuan_send_data (ctx, pkadv, pkadvlen-1);
626       xfree (pkadv);
627     }
628   else
629     rc = assuan_send_data (ctx, pk, pklen);
630
631  leave:
632   xfree (pk);
633   xfree (cert);
634   return rc;
635 }
636
637
638 \f
639 static const char hlp_setdata[] =
640   "SETDATA [--append] <hexstring>\n"
641   "\n"
642   "The client should use this command to tell us the data he want to sign.\n"
643   "With the option --append, the data is appended to the data set by a\n"
644   "previous SETDATA command.";
645 static gpg_error_t
646 cmd_setdata (assuan_context_t ctx, char *line)
647 {
648   ctrl_t ctrl = assuan_get_pointer (ctx);
649   int append;
650   int n, i, off;
651   char *p;
652   unsigned char *buf;
653
654   append = (ctrl->in_data.value && has_option (line, "--append"));
655
656   line = skip_options (line);
657
658   if (locked_session && locked_session != ctrl->server_local)
659     return gpg_error (GPG_ERR_LOCKED);
660
661   /* Parse the hexstring. */
662   for (p=line,n=0; hexdigitp (p); p++, n++)
663     ;
664   if (*p)
665     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
666   if (!n)
667     return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
668   if ((n&1))
669     return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
670   n /= 2;
671   if (append)
672     {
673       if (ctrl->in_data.valuelen + n > MAXLEN_SETDATA)
674         return set_error (GPG_ERR_TOO_LARGE,
675                           "limit on total size of data reached");
676       buf = xtrymalloc (ctrl->in_data.valuelen + n);
677     }
678   else
679     buf = xtrymalloc (n);
680   if (!buf)
681     return out_of_core ();
682
683   if (append)
684     {
685       memcpy (buf, ctrl->in_data.value, ctrl->in_data.valuelen);
686       off = ctrl->in_data.valuelen;
687     }
688   else
689     off = 0;
690   for (p=line, i=0; i < n; p += 2, i++)
691     buf[off+i] = xtoi_2 (p);
692
693   xfree (ctrl->in_data.value);
694   ctrl->in_data.value = buf;
695   ctrl->in_data.valuelen = off+n;
696   return 0;
697 }
698
699
700
701 static gpg_error_t
702 pin_cb (void *opaque, const char *info, char **retstr)
703 {
704   assuan_context_t ctx = opaque;
705   char *command;
706   int rc;
707   unsigned char *value;
708   size_t valuelen;
709
710   if (!retstr)
711     {
712       /* We prompt for pinpad entry.  To make sure that the popup has
713          been show we use an inquire and not just a status message.
714          We ignore any value returned.  */
715       if (info)
716         {
717           log_debug ("prompting for pinpad entry '%s'\n", info);
718           rc = gpgrt_asprintf (&command, "POPUPPINPADPROMPT %s", info);
719           if (rc < 0)
720             return gpg_error (gpg_err_code_from_errno (errno));
721           rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
722           xfree (command);
723         }
724       else
725         {
726           log_debug ("dismiss pinpad entry prompt\n");
727           rc = assuan_inquire (ctx, "DISMISSPINPADPROMPT",
728                                &value, &valuelen, MAXLEN_PIN);
729         }
730       if (!rc)
731         xfree (value);
732       return rc;
733     }
734
735   *retstr = NULL;
736   log_debug ("asking for PIN '%s'\n", info);
737
738   rc = gpgrt_asprintf (&command, "NEEDPIN %s", info);
739   if (rc < 0)
740     return gpg_error (gpg_err_code_from_errno (errno));
741
742   /* Fixme: Write an inquire function which returns the result in
743      secure memory and check all further handling of the PIN. */
744   rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
745   xfree (command);
746   if (rc)
747     return rc;
748
749   if (!valuelen || value[valuelen-1])
750     {
751       /* We require that the returned value is an UTF-8 string */
752       xfree (value);
753       return gpg_error (GPG_ERR_INV_RESPONSE);
754     }
755   *retstr = (char*)value;
756   return 0;
757 }
758
759
760 static const char hlp_pksign[] =
761   "PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5]] <hexified_id>\n"
762   "\n"
763   "The --hash option is optional; the default is SHA1.";
764 static gpg_error_t
765 cmd_pksign (assuan_context_t ctx, char *line)
766 {
767   ctrl_t ctrl = assuan_get_pointer (ctx);
768   int rc;
769   unsigned char *outdata;
770   size_t outdatalen;
771   char *keyidstr;
772   int hash_algo;
773   card_t card;
774   int direct = 0;
775
776   if (has_option (line, "--hash=rmd160"))
777     hash_algo = GCRY_MD_RMD160;
778   else if (has_option (line, "--hash=sha1"))
779     hash_algo = GCRY_MD_SHA1;
780   else if (has_option (line, "--hash=sha224"))
781     hash_algo = GCRY_MD_SHA224;
782   else if (has_option (line, "--hash=sha256"))
783     hash_algo = GCRY_MD_SHA256;
784   else if (has_option (line, "--hash=sha384"))
785     hash_algo = GCRY_MD_SHA384;
786   else if (has_option (line, "--hash=sha512"))
787     hash_algo = GCRY_MD_SHA512;
788   else if (has_option (line, "--hash=md5"))
789     hash_algo = GCRY_MD_MD5;
790   else if (!strstr (line, "--"))
791     hash_algo = GCRY_MD_SHA1;
792   else
793     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
794
795   line = skip_options (line);
796
797   if ((rc = open_card (ctrl)))
798     return rc;
799
800   /* We have to use a copy of the key ID because the function may use
801      the pin_cb which in turn uses the assuan line buffer and thus
802      overwriting the original line with the keyid */
803   keyidstr = xtrystrdup (line);
804   if (!keyidstr)
805     return out_of_core ();
806
807   /* When it's a keygrip, we directly use the card, with no change of
808      ctrl->card_ctx. */
809   if (strlen (keyidstr) == 40)
810     {
811       card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr);
812       direct = 1;
813     }
814   else
815     card = ctrl->card_ctx;
816
817   if (card)
818     {
819       if (direct)
820         card_ref (card);
821       rc = app_sign (card, ctrl,
822                      keyidstr, hash_algo,
823                      pin_cb, ctx,
824                      ctrl->in_data.value, ctrl->in_data.valuelen,
825                      &outdata, &outdatalen);
826       if (direct)
827         card_unref (card);
828     }
829   else
830     rc = gpg_error (GPG_ERR_NO_SECKEY);
831
832   xfree (keyidstr);
833   if (rc)
834     {
835       log_error ("app_sign failed: %s\n", gpg_strerror (rc));
836     }
837   else
838     {
839       rc = assuan_send_data (ctx, outdata, outdatalen);
840       xfree (outdata);
841       if (rc)
842         return rc; /* that is already an assuan error code */
843     }
844
845   return rc;
846 }
847
848
849 static const char hlp_pkauth[] =
850   "PKAUTH <hexified_id>";
851 static gpg_error_t
852 cmd_pkauth (assuan_context_t ctx, char *line)
853 {
854   ctrl_t ctrl = assuan_get_pointer (ctx);
855   int rc;
856   unsigned char *outdata;
857   size_t outdatalen;
858   char *keyidstr;
859   card_t card;
860   int direct = 0;
861
862   if ((rc = open_card (ctrl)))
863     return rc;
864
865   if (!ctrl->card_ctx)
866     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
867
868  /* We have to use a copy of the key ID because the function may use
869      the pin_cb which in turn uses the assuan line buffer and thus
870      overwriting the original line with the keyid */
871   keyidstr = xtrystrdup (line);
872   if (!keyidstr)
873     return out_of_core ();
874
875   /* When it's a keygrip, we directly use CARD, with no change of
876      ctrl->card_ctx. */
877   if (strlen (keyidstr) == 40)
878     {
879       card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr);
880       direct = 1;
881     }
882   else
883     card = ctrl->card_ctx;
884
885   if (card)
886     {
887       if (direct)
888         card_ref (card);
889       rc = app_auth (card, ctrl, keyidstr, pin_cb, ctx,
890                      ctrl->in_data.value, ctrl->in_data.valuelen,
891                      &outdata, &outdatalen);
892       if (direct)
893         card_unref (card);
894     }
895   else
896     rc = gpg_error (GPG_ERR_NO_SECKEY);
897
898   xfree (keyidstr);
899   if (rc)
900     {
901       log_error ("app_auth failed: %s\n", gpg_strerror (rc));
902     }
903   else
904     {
905       rc = assuan_send_data (ctx, outdata, outdatalen);
906       xfree (outdata);
907       if (rc)
908         return rc; /* that is already an assuan error code */
909     }
910
911   return rc;
912 }
913
914
915 static const char hlp_pkdecrypt[] =
916   "PKDECRYPT <hexified_id>";
917 static gpg_error_t
918 cmd_pkdecrypt (assuan_context_t ctx, char *line)
919 {
920   ctrl_t ctrl = assuan_get_pointer (ctx);
921   int rc;
922   unsigned char *outdata;
923   size_t outdatalen;
924   char *keyidstr;
925   unsigned int infoflags;
926   card_t card;
927   int direct = 0;
928
929   if ((rc = open_card (ctrl)))
930     return rc;
931
932   keyidstr = xtrystrdup (line);
933   if (!keyidstr)
934     return out_of_core ();
935
936   /* When it's a keygrip, we directly use CARD, with no change of
937      ctrl->card_ctx. */
938   if (strlen (keyidstr) == 40)
939     {
940       card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr);
941       direct = 1;
942     }
943   else
944     card = ctrl->card_ctx;
945
946   if (card)
947     {
948       if (direct)
949         card_ref (card);
950       rc = app_decipher (card, ctrl, keyidstr, pin_cb, ctx,
951                          ctrl->in_data.value, ctrl->in_data.valuelen,
952                          &outdata, &outdatalen, &infoflags);
953       if (direct)
954         card_unref (card);
955     }
956   else
957     rc = gpg_error (GPG_ERR_NO_SECKEY);
958
959   xfree (keyidstr);
960   if (rc)
961     {
962       log_error ("app_decipher failed: %s\n", gpg_strerror (rc));
963     }
964   else
965     {
966       /* If the card driver told us that there is no padding, send a
967          status line.  If there is a padding it is assumed that the
968          caller knows what padding is used.  It would have been better
969          to always send that information but for backward
970          compatibility we can't do that.  */
971       if ((infoflags & APP_DECIPHER_INFO_NOPAD))
972         send_status_direct (ctrl, "PADDING", "0");
973       rc = assuan_send_data (ctx, outdata, outdatalen);
974       xfree (outdata);
975       if (rc)
976         return rc; /* that is already an assuan error code */
977     }
978
979   return rc;
980 }
981
982
983 static const char hlp_getattr[] =
984   "GETATTR <name>\n"
985   "\n"
986   "This command is used to retrieve data from a smartcard.  The\n"
987   "allowed names depend on the currently selected smartcard\n"
988   "application.  NAME must be percent and '+' escaped.  The value is\n"
989   "returned through status message, see the LEARN command for details.\n"
990   "\n"
991   "However, the current implementation assumes that Name is not escaped;\n"
992   "this works as long as no one uses arbitrary escaping. \n"
993   "\n"
994   "Note, that this function may even be used on a locked card.";
995 static gpg_error_t
996 cmd_getattr (assuan_context_t ctx, char *line)
997 {
998   ctrl_t ctrl = assuan_get_pointer (ctx);
999   int rc;
1000   const char *keyword;
1001
1002   if ((rc = open_card (ctrl)))
1003     return rc;
1004
1005   keyword = line;
1006   for (; *line && !spacep (line); line++)
1007     ;
1008   if (*line)
1009       *line++ = 0;
1010
1011   /* (We ignore any garbage for now.) */
1012
1013   /* FIXME: Applications should not return sensitive data if the card
1014      is locked.  */
1015   rc = app_getattr (ctrl->card_ctx, ctrl, keyword);
1016
1017   return rc;
1018 }
1019
1020
1021 static const char hlp_setattr[] =
1022   "SETATTR [--inquire] <name> <value> \n"
1023   "\n"
1024   "This command is used to store data on a smartcard.  The allowed\n"
1025   "names and values are depend on the currently selected smartcard\n"
1026   "application.  NAME and VALUE must be percent and '+' escaped.\n"
1027   "\n"
1028   "However, the current implementation assumes that NAME is not\n"
1029   "escaped; this works as long as no one uses arbitrary escaping.\n"
1030   "\n"
1031   "If the option --inquire is used, VALUE shall not be given; instead\n"
1032   "an inquiry using the keyword \"VALUE\" is used to retrieve it.  The\n"
1033   "value is in this case considered to be confidential and not logged.\n"
1034   "\n"
1035   "A PIN will be requested for most NAMEs.  See the corresponding\n"
1036   "setattr function of the actually used application (app-*.c) for\n"
1037   "details.";
1038 static gpg_error_t
1039 cmd_setattr (assuan_context_t ctx, char *orig_line)
1040 {
1041   ctrl_t ctrl = assuan_get_pointer (ctx);
1042   gpg_error_t err;
1043   char *keyword;
1044   int keywordlen;
1045   size_t nbytes;
1046   char *line, *linebuf;
1047   int opt_inquire;
1048
1049   opt_inquire = has_option (orig_line, "--inquire");
1050   orig_line = skip_options (orig_line);
1051
1052   if ((err = open_card (ctrl)))
1053     return err;
1054
1055   /* We need to use a copy of LINE, because PIN_CB uses the same
1056      context and thus reuses the Assuan provided LINE. */
1057   line = linebuf = xtrystrdup (orig_line);
1058   if (!line)
1059     return out_of_core ();
1060
1061   keyword = line;
1062   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1063     ;
1064   if (*line)
1065       *line++ = 0;
1066   while (spacep (line))
1067     line++;
1068   if (opt_inquire)
1069     {
1070       unsigned char *value;
1071
1072       assuan_begin_confidential (ctx);
1073       err = assuan_inquire (ctx, "VALUE", &value, &nbytes, MAXLEN_SETATTRDATA);
1074       assuan_end_confidential (ctx);
1075       if (!err)
1076         {
1077           err = app_setattr (ctrl->card_ctx, ctrl, keyword, pin_cb, ctx,
1078                              value, nbytes);
1079           wipememory (value, nbytes);
1080           xfree (value);
1081         }
1082
1083    }
1084   else
1085     {
1086       nbytes = percent_plus_unescape_inplace (line, 0);
1087       err = app_setattr (ctrl->card_ctx, ctrl, keyword, pin_cb, ctx,
1088                          (const unsigned char*)line, nbytes);
1089     }
1090
1091   xfree (linebuf);
1092   return err;
1093 }
1094
1095
1096 static const char hlp_writecert[] =
1097   "WRITECERT <hexified_certid>\n"
1098   "\n"
1099   "This command is used to store a certificate on a smartcard.  The\n"
1100   "allowed certids depend on the currently selected smartcard\n"
1101   "application. The actual certifciate is requested using the inquiry\n"
1102   "\"CERTDATA\" and needs to be provided in its raw (e.g. DER) form.\n"
1103   "\n"
1104   "In almost all cases a PIN will be requested.  See the related\n"
1105   "writecert function of the actually used application (app-*.c) for\n"
1106   "details.";
1107 static gpg_error_t
1108 cmd_writecert (assuan_context_t ctx, char *line)
1109 {
1110   ctrl_t ctrl = assuan_get_pointer (ctx);
1111   int rc;
1112   char *certid;
1113   unsigned char *certdata;
1114   size_t certdatalen;
1115
1116   line = skip_options (line);
1117
1118   if (!*line)
1119     return set_error (GPG_ERR_ASS_PARAMETER, "no certid given");
1120   certid = line;
1121   while (*line && !spacep (line))
1122     line++;
1123   *line = 0;
1124
1125   if ((rc = open_card (ctrl)))
1126     return rc;
1127
1128   if (!ctrl->card_ctx)
1129     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1130
1131   certid = xtrystrdup (certid);
1132   if (!certid)
1133     return out_of_core ();
1134
1135   /* Now get the actual keydata. */
1136   rc = assuan_inquire (ctx, "CERTDATA",
1137                        &certdata, &certdatalen, MAXLEN_CERTDATA);
1138   if (rc)
1139     {
1140       xfree (certid);
1141       return rc;
1142     }
1143
1144   /* Write the certificate to the card. */
1145   rc = app_writecert (ctrl->card_ctx, ctrl, certid,
1146                       pin_cb, ctx, certdata, certdatalen);
1147   xfree (certid);
1148   xfree (certdata);
1149
1150   return rc;
1151 }
1152
1153
1154 static const char hlp_writekey[] =
1155   "WRITEKEY [--force] <keyid> \n"
1156   "\n"
1157   "This command is used to store a secret key on a smartcard.  The\n"
1158   "allowed keyids depend on the currently selected smartcard\n"
1159   "application. The actual keydata is requested using the inquiry\n"
1160   "\"KEYDATA\" and need to be provided without any protection.  With\n"
1161   "--force set an existing key under this KEYID will get overwritten.\n"
1162   "The keydata is expected to be the usual canonical encoded\n"
1163   "S-expression.\n"
1164   "\n"
1165   "A PIN will be requested for most NAMEs.  See the corresponding\n"
1166   "writekey function of the actually used application (app-*.c) for\n"
1167   "details.";
1168 static gpg_error_t
1169 cmd_writekey (assuan_context_t ctx, char *line)
1170 {
1171   ctrl_t ctrl = assuan_get_pointer (ctx);
1172   int rc;
1173   char *keyid;
1174   int force = has_option (line, "--force");
1175   unsigned char *keydata;
1176   size_t keydatalen;
1177
1178   line = skip_options (line);
1179
1180   if (!*line)
1181     return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1182   keyid = line;
1183   while (*line && !spacep (line))
1184     line++;
1185   *line = 0;
1186
1187   if ((rc = open_card (ctrl)))
1188     return rc;
1189
1190   if (!ctrl->card_ctx)
1191     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1192
1193   keyid = xtrystrdup (keyid);
1194   if (!keyid)
1195     return out_of_core ();
1196
1197   /* Now get the actual keydata. */
1198   assuan_begin_confidential (ctx);
1199   rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1200   assuan_end_confidential (ctx);
1201   if (rc)
1202     {
1203       xfree (keyid);
1204       return rc;
1205     }
1206
1207   /* Write the key to the card. */
1208   rc = app_writekey (ctrl->card_ctx, ctrl, keyid, force? 1:0,
1209                      pin_cb, ctx, keydata, keydatalen);
1210   xfree (keyid);
1211   xfree (keydata);
1212
1213   return rc;
1214 }
1215
1216
1217 static const char hlp_genkey[] =
1218   "GENKEY [--force] [--timestamp=<isodate>] <keyref>\n"
1219   "\n"
1220   "Generate a key on-card identified by <keyref>, which is application\n"
1221   "specific.  Return values are also application specific.  For OpenPGP\n"
1222   "cards 3 status lines are returned:\n"
1223   "\n"
1224   "  S KEY-FPR  <hexstring>\n"
1225   "  S KEY-CREATED-AT <seconds_since_epoch>\n"
1226   "  S KEY-DATA [-|p|n] <hexdata>\n"
1227   "\n"
1228   "  'p' and 'n' are the names of the RSA parameters; '-' is used to\n"
1229   "  indicate that HEXDATA is the first chunk of a parameter given\n"
1230   "  by the next KEY-DATA.  Only used by GnuPG version < 2.1.\n"
1231   "\n"
1232   "--force is required to overwrite an already existing key.  The\n"
1233   "KEY-CREATED-AT is required for further processing because it is\n"
1234   "part of the hashed key material for the fingerprint.\n"
1235   "\n"
1236   "If --timestamp is given an OpenPGP key will be created using this\n"
1237   "value.  The value needs to be in ISO Format; e.g.\n"
1238   "\"--timestamp=20030316T120000\" and after 1970-01-01 00:00:00.\n"
1239   "\n"
1240   "The public part of the key can also later be retrieved using the\n"
1241   "READKEY command.";
1242 static gpg_error_t
1243 cmd_genkey (assuan_context_t ctx, char *line)
1244 {
1245   ctrl_t ctrl = assuan_get_pointer (ctx);
1246   gpg_error_t err;
1247   char *keyref_buffer = NULL;
1248   char *keyref;
1249   int force;
1250   const char *s;
1251   char *opt_algo = NULL;
1252   time_t timestamp;
1253
1254   force = has_option (line, "--force");
1255
1256   if ((s=has_option_name (line, "--timestamp")))
1257     {
1258       if (*s != '=')
1259         return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1260       timestamp = isotime2epoch (s+1);
1261       if (timestamp < 1)
1262         return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1263     }
1264   else
1265     timestamp = 0;
1266
1267   err = get_option_value (line, "--algo", &opt_algo);
1268   if (err)
1269     goto leave;
1270
1271   line = skip_options (line);
1272   if (!*line)
1273     return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1274   keyref = line;
1275   while (*line && !spacep (line))
1276     line++;
1277   *line = 0;
1278
1279   if ((err = open_card (ctrl)))
1280     goto leave;
1281
1282   if (!ctrl->card_ctx)
1283     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1284
1285   keyref = keyref_buffer = xtrystrdup (keyref);
1286   if (!keyref)
1287     {
1288       err = gpg_error_from_syserror ();
1289       goto leave;
1290     }
1291   err = app_genkey (ctrl->card_ctx, ctrl, keyref, opt_algo,
1292                     force? APP_GENKEY_FLAG_FORCE : 0,
1293                     timestamp, pin_cb, ctx);
1294
1295  leave:
1296   xfree (keyref_buffer);
1297   xfree (opt_algo);
1298   return err;
1299 }
1300
1301
1302 static const char hlp_random[] =
1303   "RANDOM <nbytes>\n"
1304   "\n"
1305   "Get NBYTES of random from the card and send them back as data.\n"
1306   "This usually involves EEPROM write on the card and thus excessive\n"
1307   "use of this command may destroy the card.\n"
1308   "\n"
1309   "Note, that this function may be even be used on a locked card.";
1310 static gpg_error_t
1311 cmd_random (assuan_context_t ctx, char *line)
1312 {
1313   ctrl_t ctrl = assuan_get_pointer (ctx);
1314   int rc;
1315   size_t nbytes;
1316   unsigned char *buffer;
1317
1318   if (!*line)
1319     return set_error (GPG_ERR_ASS_PARAMETER,
1320                       "number of requested bytes missing");
1321   nbytes = strtoul (line, NULL, 0);
1322
1323   if ((rc = open_card (ctrl)))
1324     return rc;
1325
1326   if (!ctrl->card_ctx)
1327     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1328
1329   buffer = xtrymalloc (nbytes);
1330   if (!buffer)
1331     return out_of_core ();
1332
1333   rc = app_get_challenge (ctrl->card_ctx, ctrl, nbytes, buffer);
1334   if (!rc)
1335     {
1336       rc = assuan_send_data (ctx, buffer, nbytes);
1337       xfree (buffer);
1338       return rc; /* that is already an assuan error code */
1339     }
1340   xfree (buffer);
1341
1342   return rc;
1343 }
1344
1345
1346 \f
1347 static const char hlp_passwd[] =
1348   "PASSWD [--reset] [--nullpin] [--clear] <chvno>\n"
1349   "\n"
1350   "Change the PIN or, if --reset is given, reset the retry counter of\n"
1351   "the card holder verification vector CHVNO.  The option --nullpin is\n"
1352   "used for TCOS cards to set the initial PIN.  The option --clear clears\n"
1353   "the security status associated with the PIN so that the PIN needs to\n"
1354   "be presented again. The format of CHVNO depends on the card application.";
1355 static gpg_error_t
1356 cmd_passwd (assuan_context_t ctx, char *line)
1357 {
1358   ctrl_t ctrl = assuan_get_pointer (ctx);
1359   int rc;
1360   char *chvnostr;
1361   unsigned int flags = 0;
1362
1363   if (has_option (line, "--reset"))
1364     flags |= APP_CHANGE_FLAG_RESET;
1365   if (has_option (line, "--nullpin"))
1366     flags |= APP_CHANGE_FLAG_NULLPIN;
1367   if (has_option (line, "--clear"))
1368     flags |= APP_CHANGE_FLAG_CLEAR;
1369
1370   line = skip_options (line);
1371
1372   if (!*line)
1373     return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1374   chvnostr = line;
1375   while (*line && !spacep (line))
1376     line++;
1377   *line = 0;
1378
1379   /* Do not allow other flags aside of --clear. */
1380   if ((flags & APP_CHANGE_FLAG_CLEAR) && (flags & ~APP_CHANGE_FLAG_CLEAR))
1381     return set_error (GPG_ERR_UNSUPPORTED_OPERATION,
1382                       "--clear used with other options");
1383
1384   if ((rc = open_card (ctrl)))
1385     return rc;
1386
1387   if (!ctrl->card_ctx)
1388     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1389
1390   chvnostr = xtrystrdup (chvnostr);
1391   if (!chvnostr)
1392     return out_of_core ();
1393   rc = app_change_pin (ctrl->card_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
1394   if (rc)
1395     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1396   xfree (chvnostr);
1397
1398   return rc;
1399 }
1400
1401
1402 static const char hlp_checkpin[] =
1403   "CHECKPIN <idstr>\n"
1404   "\n"
1405   "Perform a VERIFY operation without doing anything else.  This may\n"
1406   "be used to initialize a the PIN cache earlier to long lasting\n"
1407   "operations.  Its use is highly application dependent.\n"
1408   "\n"
1409   "For OpenPGP:\n"
1410   "\n"
1411   "   Perform a simple verify operation for CHV1 and CHV2, so that\n"
1412   "   further operations won't ask for CHV2 and it is possible to do a\n"
1413   "   cheap check on the PIN: If there is something wrong with the PIN\n"
1414   "   entry system, only the regular CHV will get blocked and not the\n"
1415   "   dangerous CHV3.  IDSTR is the usual card's serial number in hex\n"
1416   "   notation; an optional fingerprint part will get ignored.  There\n"
1417   "   is however a special mode if the IDSTR is sffixed with the\n"
1418   "   literal string \"[CHV3]\": In this case the Admin PIN is checked\n"
1419   "   if and only if the retry counter is still at 3.\n"
1420   "\n"
1421   "For Netkey:\n"
1422   "\n"
1423   "   Any of the valid PIN Ids may be used.  These are the strings:\n"
1424   "\n"
1425   "     PW1.CH       - Global password 1\n"
1426   "     PW2.CH       - Global password 2\n"
1427   "     PW1.CH.SIG   - SigG password 1\n"
1428   "     PW2.CH.SIG   - SigG password 2\n"
1429   "\n"
1430   "   For a definitive list, see the implementation in app-nks.c.\n"
1431   "   Note that we call a PW2.* PIN a \"PUK\" despite that since TCOS\n"
1432   "   3.0 they are technically alternative PINs used to mutally\n"
1433   "   unblock each other.";
1434 static gpg_error_t
1435 cmd_checkpin (assuan_context_t ctx, char *line)
1436 {
1437   ctrl_t ctrl = assuan_get_pointer (ctx);
1438   int rc;
1439   char *idstr;
1440
1441   if ((rc = open_card (ctrl)))
1442     return rc;
1443
1444   if (!ctrl->card_ctx)
1445     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1446
1447   /* We have to use a copy of the key ID because the function may use
1448      the pin_cb which in turn uses the assuan line buffer and thus
1449      overwriting the original line with the keyid. */
1450   idstr = xtrystrdup (line);
1451   if (!idstr)
1452     return out_of_core ();
1453
1454   rc = app_check_pin (ctrl->card_ctx, ctrl, idstr, pin_cb, ctx);
1455   xfree (idstr);
1456   if (rc)
1457     log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1458
1459   return rc;
1460 }
1461
1462
1463 static const char hlp_lock[] =
1464   "LOCK [--wait]\n"
1465   "\n"
1466   "Grant exclusive card access to this session.  Note that there is\n"
1467   "no lock counter used and a second lock from the same session will\n"
1468   "be ignored.  A single unlock (or RESET) unlocks the session.\n"
1469   "Return GPG_ERR_LOCKED if another session has locked the reader.\n"
1470   "\n"
1471   "If the option --wait is given the command will wait until a\n"
1472   "lock has been released.";
1473 static gpg_error_t
1474 cmd_lock (assuan_context_t ctx, char *line)
1475 {
1476   ctrl_t ctrl = assuan_get_pointer (ctx);
1477   int rc = 0;
1478
1479  retry:
1480   if (locked_session)
1481     {
1482       if (locked_session != ctrl->server_local)
1483         rc = gpg_error (GPG_ERR_LOCKED);
1484     }
1485   else
1486     locked_session = ctrl->server_local;
1487
1488 #ifdef USE_NPTH
1489   if (rc && has_option (line, "--wait"))
1490     {
1491       rc = 0;
1492       npth_sleep (1); /* Better implement an event mechanism. However,
1493                          for card operations this should be
1494                          sufficient. */
1495       /* FIXME: Need to check that the connection is still alive.
1496          This can be done by issuing status messages. */
1497       goto retry;
1498     }
1499 #endif /*USE_NPTH*/
1500
1501   if (rc)
1502     log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1503   return rc;
1504 }
1505
1506
1507 static const char hlp_unlock[] =
1508   "UNLOCK\n"
1509   "\n"
1510   "Release exclusive card access.";
1511 static gpg_error_t
1512 cmd_unlock (assuan_context_t ctx, char *line)
1513 {
1514   ctrl_t ctrl = assuan_get_pointer (ctx);
1515   int rc = 0;
1516
1517   (void)line;
1518
1519   if (locked_session)
1520     {
1521       if (locked_session != ctrl->server_local)
1522         rc = gpg_error (GPG_ERR_LOCKED);
1523       else
1524         locked_session = NULL;
1525     }
1526   else
1527     rc = gpg_error (GPG_ERR_NOT_LOCKED);
1528
1529   if (rc)
1530     log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1531   return rc;
1532 }
1533
1534
1535 static const char hlp_getinfo[] =
1536   "GETINFO <what>\n"
1537   "\n"
1538   "Multi purpose command to return certain information.  \n"
1539   "Supported values of WHAT are:\n"
1540   "\n"
1541   "  version     - Return the version of the program.\n"
1542   "  pid         - Return the process id of the server.\n"
1543   "  socket_name - Return the name of the socket.\n"
1544   "  connections - Return number of active connections.\n"
1545   "  status      - Return the status of the current reader (in the future,\n"
1546   "                may also return the status of all readers).  The status\n"
1547   "                is a list of one-character flags.  The following flags\n"
1548   "                are currently defined:\n"
1549   "                  'u'  Usable card present.\n"
1550   "                  'r'  Card removed.  A reset is necessary.\n"
1551   "                These flags are exclusive.\n"
1552   "  reader_list - Return a list of detected card readers.  Does\n"
1553   "                currently only work with the internal CCID driver.\n"
1554   "  deny_admin  - Returns OK if admin commands are not allowed or\n"
1555   "                GPG_ERR_GENERAL if admin commands are allowed.\n"
1556   "  app_list    - Return a list of supported applications.  One\n"
1557   "                application per line, fields delimited by colons,\n"
1558   "                first field is the name.\n"
1559   "  card_list   - Return a list of serial numbers of active cards,\n"
1560   "                using a status response.";
1561 static gpg_error_t
1562 cmd_getinfo (assuan_context_t ctx, char *line)
1563 {
1564   int rc = 0;
1565
1566   if (!strcmp (line, "version"))
1567     {
1568       const char *s = VERSION;
1569       rc = assuan_send_data (ctx, s, strlen (s));
1570     }
1571   else if (!strcmp (line, "pid"))
1572     {
1573       char numbuf[50];
1574
1575       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1576       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1577     }
1578   else if (!strcmp (line, "socket_name"))
1579     {
1580       const char *s = scd_get_socket_name ();
1581
1582       if (s)
1583         rc = assuan_send_data (ctx, s, strlen (s));
1584       else
1585         rc = gpg_error (GPG_ERR_NO_DATA);
1586     }
1587   else if (!strcmp (line, "connections"))
1588     {
1589       char numbuf[20];
1590
1591       snprintf (numbuf, sizeof numbuf, "%d", get_active_connection_count ());
1592       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1593     }
1594   else if (!strcmp (line, "status"))
1595     {
1596       ctrl_t ctrl = assuan_get_pointer (ctx);
1597       char flag;
1598
1599       if (open_card (ctrl))
1600         flag = 'r';
1601       else
1602         flag = 'u';
1603
1604       rc = assuan_send_data (ctx, &flag, 1);
1605     }
1606   else if (!strcmp (line, "reader_list"))
1607     {
1608 #ifdef HAVE_LIBUSB
1609       char *s = ccid_get_reader_list ();
1610 #else
1611       char *s = NULL;
1612 #endif
1613
1614       if (s)
1615         rc = assuan_send_data (ctx, s, strlen (s));
1616       else
1617         rc = gpg_error (GPG_ERR_NO_DATA);
1618       xfree (s);
1619     }
1620   else if (!strcmp (line, "deny_admin"))
1621     rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1622   else if (!strcmp (line, "app_list"))
1623     {
1624       char *s = get_supported_applications ();
1625       if (s)
1626         rc = assuan_send_data (ctx, s, strlen (s));
1627       else
1628         rc = 0;
1629       xfree (s);
1630     }
1631   else if (!strcmp (line, "card_list"))
1632     {
1633       ctrl_t ctrl = assuan_get_pointer (ctx);
1634
1635       rc = app_send_card_list (ctrl);
1636     }
1637   else
1638     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1639   return rc;
1640 }
1641
1642
1643 static const char hlp_restart[] =
1644   "RESTART\n"
1645   "\n"
1646   "Restart the current connection; this is a kind of warm reset.  It\n"
1647   "deletes the context used by this connection but does not send a\n"
1648   "RESET to the card.  Thus the card itself won't get reset. \n"
1649   "\n"
1650   "This is used by gpg-agent to reuse a primary pipe connection and\n"
1651   "may be used by clients to backup from a conflict in the serial\n"
1652   "command; i.e. to select another application.";
1653 static gpg_error_t
1654 cmd_restart (assuan_context_t ctx, char *line)
1655 {
1656   ctrl_t ctrl = assuan_get_pointer (ctx);
1657   card_t card = ctrl->card_ctx;
1658
1659   (void)line;
1660
1661   if (card)
1662     {
1663       ctrl->card_ctx = NULL;
1664       card_unref (card);
1665     }
1666   if (locked_session && ctrl->server_local == locked_session)
1667     {
1668       locked_session = NULL;
1669       log_info ("implicitly unlocking due to RESTART\n");
1670     }
1671   return 0;
1672 }
1673
1674
1675 static const char hlp_disconnect[] =
1676   "DISCONNECT\n"
1677   "\n"
1678   "Disconnect the card if the backend supports a disconnect operation.";
1679 static gpg_error_t
1680 cmd_disconnect (assuan_context_t ctx, char *line)
1681 {
1682   ctrl_t ctrl = assuan_get_pointer (ctx);
1683
1684   (void)line;
1685
1686   if (!ctrl->card_ctx)
1687     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1688
1689   apdu_disconnect (ctrl->card_ctx->slot);
1690   return 0;
1691 }
1692
1693
1694
1695 static const char hlp_apdu[] =
1696   "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n"
1697   "\n"
1698   "Send an APDU to the current reader.  This command bypasses the high\n"
1699   "level functions and sends the data directly to the card.  HEXSTRING\n"
1700   "is expected to be a proper APDU.  If HEXSTRING is not given no\n"
1701   "commands are set to the card but the command will implictly check\n"
1702   "whether the card is ready for use. \n"
1703   "\n"
1704   "Using the option \"--atr\" returns the ATR of the card as a status\n"
1705   "message before any data like this:\n"
1706   "  S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1\n"
1707   "\n"
1708   "Using the option --more handles the card status word MORE_DATA\n"
1709   "(61xx) and concatenates all responses to one block.\n"
1710   "\n"
1711   "Using the option \"--exlen\" the returned APDU may use extended\n"
1712   "length up to N bytes.  If N is not given a default value is used\n"
1713   "(currently 4096).";
1714 static gpg_error_t
1715 cmd_apdu (assuan_context_t ctx, char *line)
1716 {
1717   ctrl_t ctrl = assuan_get_pointer (ctx);
1718   card_t card;
1719   int rc;
1720   unsigned char *apdu;
1721   size_t apdulen;
1722   int with_atr;
1723   int handle_more;
1724   const char *s;
1725   size_t exlen;
1726
1727   if (has_option (line, "--dump-atr"))
1728     with_atr = 2;
1729   else
1730     with_atr = has_option (line, "--atr");
1731   handle_more = has_option (line, "--more");
1732
1733   if ((s=has_option_name (line, "--exlen")))
1734     {
1735       if (*s == '=')
1736         exlen = strtoul (s+1, NULL, 0);
1737       else
1738         exlen = 4096;
1739     }
1740   else
1741     exlen = 0;
1742
1743   line = skip_options (line);
1744
1745   if ((rc = open_card (ctrl)))
1746     return rc;
1747
1748   card = ctrl->card_ctx;
1749   if (!card)
1750     return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
1751
1752   if (with_atr)
1753     {
1754       unsigned char *atr;
1755       size_t atrlen;
1756       char hexbuf[400];
1757
1758       atr = apdu_get_atr (card->slot, &atrlen);
1759       if (!atr || atrlen > sizeof hexbuf - 2 )
1760         {
1761           rc = gpg_error (GPG_ERR_INV_CARD);
1762           goto leave;
1763         }
1764       if (with_atr == 2)
1765         {
1766           char *string, *p, *pend;
1767
1768           string = atr_dump (atr, atrlen);
1769           if (string)
1770             {
1771               for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1)
1772                 {
1773                   rc = assuan_send_data (ctx, p, pend - p + 1);
1774                   if (!rc)
1775                     rc = assuan_send_data (ctx, NULL, 0);
1776                 }
1777               if (!rc && *p)
1778                 rc = assuan_send_data (ctx, p, strlen (p));
1779               es_free (string);
1780               if (rc)
1781                 goto leave;
1782             }
1783         }
1784       else
1785         {
1786           bin2hex (atr, atrlen, hexbuf);
1787           send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1788         }
1789       xfree (atr);
1790     }
1791
1792   apdu = hex_to_buffer (line, &apdulen);
1793   if (!apdu)
1794     {
1795       rc = gpg_error_from_syserror ();
1796       goto leave;
1797     }
1798   if (apdulen)
1799     {
1800       unsigned char *result = NULL;
1801       size_t resultlen;
1802
1803       rc = apdu_send_direct (card->slot, exlen,
1804                              apdu, apdulen, handle_more,
1805                              NULL, &result, &resultlen);
1806       if (rc)
1807         log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1808       else
1809         {
1810           rc = assuan_send_data (ctx, result, resultlen);
1811           xfree (result);
1812         }
1813     }
1814   xfree (apdu);
1815
1816  leave:
1817   return rc;
1818 }
1819
1820
1821 static const char hlp_killscd[] =
1822   "KILLSCD\n"
1823   "\n"
1824   "Commit suicide.";
1825 static gpg_error_t
1826 cmd_killscd (assuan_context_t ctx, char *line)
1827 {
1828   ctrl_t ctrl = assuan_get_pointer (ctx);
1829
1830   (void)line;
1831
1832   ctrl->server_local->stopme = 1;
1833   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
1834   return 0;
1835 }
1836
1837
1838 static const char hlp_keyinfo[] =
1839   "KEYINFO [--list] [--data] <keygrip>\n"
1840   "\n"
1841   "Return information about the key specified by the KEYGRIP.  If the\n"
1842   "key is not available GPG_ERR_NOT_FOUND is returned.  If the option\n"
1843   "--list is given the keygrip is ignored and information about all\n"
1844   "available keys are returned.  Unless --data is given, the\n"
1845   "information is returned as a status line using the format:\n"
1846   "\n"
1847   "  KEYINFO <keygrip> T <serialno> <idstr>\n"
1848   "\n"
1849   "KEYGRIP is the keygrip.\n"
1850   "\n"
1851   "SERIALNO is an ASCII string with the serial number of the\n"
1852   "         smartcard.  If the serial number is not known a single\n"
1853   "         dash '-' is used instead.\n"
1854   "\n"
1855   "IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it\n"
1856   "      is not known a dash is used instead.\n"
1857   "\n"
1858   "More information may be added in the future.";
1859 static gpg_error_t
1860 cmd_keyinfo (assuan_context_t ctx, char *line)
1861 {
1862   int list_mode;
1863   int opt_data;
1864   int action;
1865   char *keygrip_str;
1866   ctrl_t ctrl = assuan_get_pointer (ctx);
1867   card_t card;
1868
1869   list_mode = has_option (line, "--list");
1870   opt_data = has_option (line, "--data");
1871   line = skip_options (line);
1872
1873   if (list_mode)
1874     keygrip_str = NULL;
1875   else
1876     keygrip_str = line;
1877
1878   if (opt_data)
1879     action = KEYGRIP_ACTION_SEND_DATA;
1880   else
1881     action = KEYGRIP_ACTION_WRITE_STATUS;
1882
1883   card = app_do_with_keygrip (ctrl, action, keygrip_str);
1884
1885   if (!list_mode && !card)
1886     return gpg_error (GPG_ERR_NOT_FOUND);
1887   return 0;
1888 }
1889
1890
1891 /* Send a keyinfo string as used by the KEYGRIP_ACTION_SEND_DATA.  If
1892  * DATA is true the string is emitted as a data line, else as a status
1893  * line.  */
1894 void
1895 send_keyinfo (ctrl_t ctrl, int data, const char *keygrip_str,
1896               const char *serialno, const char *idstr)
1897 {
1898   char *string;
1899   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1900
1901   string = xtryasprintf ("%s T %s %s%s", keygrip_str,
1902                          serialno? serialno : "-",
1903                          idstr? idstr : "-",
1904                          data? "\n" : "");
1905
1906   if (!string)
1907     return;
1908
1909   if (!data)
1910     assuan_write_status (ctx, "KEYINFO", string);
1911   else
1912     assuan_send_data (ctx, string, strlen (string));
1913
1914   xfree (string);
1915   return;
1916 }
1917
1918
1919 \f
1920 /* Tell the assuan library about our commands */
1921 static int
1922 register_commands (assuan_context_t ctx)
1923 {
1924   static struct {
1925     const char *name;
1926     assuan_handler_t handler;
1927     const char * const help;
1928   } table[] = {
1929     { "SERIALNO",     cmd_serialno, hlp_serialno },
1930     { "LEARN",        cmd_learn,    hlp_learn },
1931     { "READCERT",     cmd_readcert, hlp_readcert },
1932     { "READKEY",      cmd_readkey,  hlp_readkey },
1933     { "SETDATA",      cmd_setdata,  hlp_setdata },
1934     { "PKSIGN",       cmd_pksign,   hlp_pksign },
1935     { "PKAUTH",       cmd_pkauth,   hlp_pkauth },
1936     { "PKDECRYPT",    cmd_pkdecrypt,hlp_pkdecrypt },
1937     { "INPUT",        NULL },
1938     { "OUTPUT",       NULL },
1939     { "GETATTR",      cmd_getattr,  hlp_getattr },
1940     { "SETATTR",      cmd_setattr,  hlp_setattr },
1941     { "WRITECERT",    cmd_writecert,hlp_writecert },
1942     { "WRITEKEY",     cmd_writekey, hlp_writekey },
1943     { "GENKEY",       cmd_genkey,   hlp_genkey },
1944     { "RANDOM",       cmd_random,   hlp_random },
1945     { "PASSWD",       cmd_passwd,   hlp_passwd },
1946     { "CHECKPIN",     cmd_checkpin, hlp_checkpin },
1947     { "LOCK",         cmd_lock,     hlp_lock },
1948     { "UNLOCK",       cmd_unlock,   hlp_unlock },
1949     { "GETINFO",      cmd_getinfo,  hlp_getinfo },
1950     { "RESTART",      cmd_restart,  hlp_restart },
1951     { "DISCONNECT",   cmd_disconnect,hlp_disconnect },
1952     { "APDU",         cmd_apdu,     hlp_apdu },
1953     { "KILLSCD",      cmd_killscd,  hlp_killscd },
1954     { "KEYINFO",      cmd_keyinfo,  hlp_keyinfo },
1955     { NULL }
1956   };
1957   int i, rc;
1958
1959   for (i=0; table[i].name; i++)
1960     {
1961       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
1962                                     table[i].help);
1963       if (rc)
1964         return rc;
1965     }
1966   assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1967
1968   assuan_register_reset_notify (ctx, reset_notify);
1969   assuan_register_option_handler (ctx, option_handler);
1970   return 0;
1971 }
1972
1973
1974 /* Startup the server.  If FD is given as -1 this is simple pipe
1975    server, otherwise it is a regular server.  Returns true if there
1976    are no more active asessions.  */
1977 int
1978 scd_command_handler (ctrl_t ctrl, int fd)
1979 {
1980   int rc;
1981   assuan_context_t ctx = NULL;
1982   int stopme;
1983
1984   rc = assuan_new (&ctx);
1985   if (rc)
1986     {
1987       log_error ("failed to allocate assuan context: %s\n",
1988                  gpg_strerror (rc));
1989       scd_exit (2);
1990     }
1991
1992   if (fd == -1)
1993     {
1994       assuan_fd_t filedes[2];
1995
1996       filedes[0] = assuan_fdopen (0);
1997       filedes[1] = assuan_fdopen (1);
1998       rc = assuan_init_pipe_server (ctx, filedes);
1999     }
2000   else
2001     {
2002       rc = assuan_init_socket_server (ctx, INT2FD(fd),
2003                                       ASSUAN_SOCKET_SERVER_ACCEPTED);
2004     }
2005   if (rc)
2006     {
2007       log_error ("failed to initialize the server: %s\n",
2008                  gpg_strerror(rc));
2009       scd_exit (2);
2010     }
2011   rc = register_commands (ctx);
2012   if (rc)
2013     {
2014       log_error ("failed to register commands with Assuan: %s\n",
2015                  gpg_strerror(rc));
2016       scd_exit (2);
2017     }
2018   assuan_set_pointer (ctx, ctrl);
2019
2020   /* Allocate and initialize the server object.  Put it into the list
2021      of active sessions. */
2022   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2023   ctrl->server_local->next_session = session_list;
2024   session_list = ctrl->server_local;
2025   ctrl->server_local->ctrl_backlink = ctrl;
2026   ctrl->server_local->assuan_ctx = ctx;
2027
2028   /* Command processing loop. */
2029   for (;;)
2030     {
2031       rc = assuan_accept (ctx);
2032       if (rc == -1)
2033         {
2034           break;
2035         }
2036       else if (rc)
2037         {
2038           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2039           break;
2040         }
2041
2042       rc = assuan_process (ctx);
2043       if (rc)
2044         {
2045           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2046           continue;
2047         }
2048     }
2049
2050   /* Cleanup.  We don't send an explicit reset to the card.  */
2051   do_reset (ctrl, 0);
2052
2053   /* Release the server object.  */
2054   if (session_list == ctrl->server_local)
2055     session_list = ctrl->server_local->next_session;
2056   else
2057     {
2058       struct server_local_s *sl;
2059
2060       for (sl=session_list; sl->next_session; sl = sl->next_session)
2061         if (sl->next_session == ctrl->server_local)
2062           break;
2063       if (!sl->next_session)
2064           BUG ();
2065       sl->next_session = ctrl->server_local->next_session;
2066     }
2067   stopme = ctrl->server_local->stopme;
2068   xfree (ctrl->server_local);
2069   ctrl->server_local = NULL;
2070
2071   /* Release the Assuan context.  */
2072   assuan_release (ctx);
2073
2074   if (stopme)
2075     scd_exit (0);
2076
2077   /* If there are no more sessions return true.  */
2078   return !session_list;
2079 }
2080
2081
2082 /* Clear the current application info for CARD from all sessions.
2083  * This is used while deallocating a card.  */
2084 void
2085 scd_clear_current_app (card_t card)
2086 {
2087   struct server_local_s *sl;
2088
2089   for (sl=session_list; sl; sl = sl->next_session)
2090     {
2091       if (sl->ctrl_backlink->card_ctx == card)
2092         sl->ctrl_backlink->current_apptype = APPTYPE_NONE;
2093     }
2094 }
2095
2096 /* Send a line with status information via assuan and escape all given
2097    buffers. The variable elements are pairs of (char *, size_t),
2098    terminated with a (NULL, 0). */
2099 void
2100 send_status_info (ctrl_t ctrl, const char *keyword, ...)
2101 {
2102   va_list arg_ptr;
2103   const unsigned char *value;
2104   size_t valuelen;
2105   char buf[950], *p;
2106   size_t n;
2107   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2108
2109   va_start (arg_ptr, keyword);
2110
2111   p = buf;
2112   n = 0;
2113   while ( (value = va_arg (arg_ptr, const unsigned char *))
2114            && n < DIM (buf)-2 )
2115     {
2116       valuelen = va_arg (arg_ptr, size_t);
2117       if (!valuelen)
2118         continue; /* empty buffer */
2119       if (n)
2120         {
2121           *p++ = ' ';
2122           n++;
2123         }
2124       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
2125         {
2126           if (*value == '+' || *value == '\"' || *value == '%'
2127               || *value < ' ')
2128             {
2129               sprintf (p, "%%%02X", *value);
2130               p += 3;
2131               n += 2;
2132             }
2133           else if (*value == ' ')
2134             *p++ = '+';
2135           else
2136             *p++ = *value;
2137         }
2138     }
2139   *p = 0;
2140   assuan_write_status (ctx, keyword, buf);
2141
2142   va_end (arg_ptr);
2143 }
2144
2145
2146 /* Send a ready formatted status line via assuan.  */
2147 void
2148 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
2149 {
2150   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2151
2152   if (strchr (args, '\n'))
2153     log_error ("error: LF detected in status line - not sending\n");
2154   else
2155     assuan_write_status (ctx, keyword, args);
2156 }
2157
2158
2159 /* This status functions expects a printf style format string.  No
2160  * filtering of the data is done instead the orintf formatted data is
2161  * send using assuan_send_status. */
2162 gpg_error_t
2163 send_status_printf (ctrl_t ctrl, const char *keyword, const char *format, ...)
2164 {
2165   gpg_error_t err;
2166   va_list arg_ptr;
2167   assuan_context_t ctx;
2168
2169   if (!ctrl || !ctrl->server_local || !(ctx = ctrl->server_local->assuan_ctx))
2170     return 0;
2171
2172   va_start (arg_ptr, format);
2173   err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
2174   va_end (arg_ptr);
2175   return err;
2176 }
2177
2178
2179 void
2180 popup_prompt (void *opaque, int on)
2181 {
2182   ctrl_t ctrl = opaque;
2183
2184   if (ctrl)
2185     {
2186       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2187
2188       if (ctx)
2189         {
2190           const char *cmd;
2191           gpg_error_t err;
2192           unsigned char *value;
2193           size_t valuelen;
2194
2195           if (on)
2196             cmd = "POPUPPINPADPROMPT --ack";
2197           else
2198             cmd = "DISMISSPINPADPROMPT";
2199           err = assuan_inquire (ctx, cmd, &value, &valuelen, 100);
2200           if (!err)
2201             xfree (value);
2202         }
2203     }
2204 }
2205
2206
2207 /* Helper to send the clients a status change notification.  Note that
2208  * this function assumes that APP is already locked.  */
2209 void
2210 send_client_notifications (card_t card, int removal)
2211 {
2212   struct {
2213     pid_t pid;
2214 #ifdef HAVE_W32_SYSTEM
2215     HANDLE handle;
2216 #else
2217     int signo;
2218 #endif
2219   } killed[50];
2220   int killidx = 0;
2221   int kidx;
2222   struct server_local_s *sl;
2223
2224   for (sl=session_list; sl; sl = sl->next_session)
2225     if (sl->ctrl_backlink && sl->ctrl_backlink->card_ctx == card)
2226       {
2227         pid_t pid;
2228 #ifdef HAVE_W32_SYSTEM
2229         HANDLE handle;
2230 #else
2231         int signo;
2232 #endif
2233
2234         if (removal)
2235           {
2236             sl->ctrl_backlink->card_ctx = NULL;
2237             sl->card_removed = 1;
2238             card_unref_locked (card);
2239           }
2240
2241         if (!sl->event_signal || !sl->assuan_ctx)
2242           continue;
2243
2244         pid = assuan_get_pid (sl->assuan_ctx);
2245
2246 #ifdef HAVE_W32_SYSTEM
2247         handle = sl->event_signal;
2248         for (kidx=0; kidx < killidx; kidx++)
2249           if (killed[kidx].pid == pid
2250               && killed[kidx].handle == handle)
2251             break;
2252         if (kidx < killidx)
2253           log_info ("event %p (%p) already triggered for client %d\n",
2254                     sl->event_signal, handle, (int)pid);
2255         else
2256           {
2257             log_info ("triggering event %p (%p) for client %d\n",
2258                       sl->event_signal, handle, (int)pid);
2259             if (!SetEvent (handle))
2260               log_error ("SetEvent(%p) failed: %s\n",
2261                          sl->event_signal, w32_strerror (-1));
2262             if (killidx < DIM (killed))
2263               {
2264                 killed[killidx].pid = pid;
2265                 killed[killidx].handle = handle;
2266                 killidx++;
2267               }
2268           }
2269 #else /*!HAVE_W32_SYSTEM*/
2270         signo = sl->event_signal;
2271
2272         if (pid != (pid_t)(-1) && pid && signo > 0)
2273           {
2274             for (kidx=0; kidx < killidx; kidx++)
2275               if (killed[kidx].pid == pid
2276                   && killed[kidx].signo == signo)
2277                 break;
2278             if (kidx < killidx)
2279               log_info ("signal %d already sent to client %d\n",
2280                         signo, (int)pid);
2281             else
2282               {
2283                 log_info ("sending signal %d to client %d\n",
2284                           signo, (int)pid);
2285                 kill (pid, signo);
2286                 if (killidx < DIM (killed))
2287                   {
2288                     killed[killidx].pid = pid;
2289                     killed[killidx].signo = signo;
2290                     killidx++;
2291                   }
2292               }
2293           }
2294 #endif /*!HAVE_W32_SYSTEM*/
2295       }
2296 }