e65262d06e3ae00f25014c8123b2f11b63a29408
[gnupg.git] / scd / command.c
1 /* command.c - SCdaemon command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3  *               2007  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 <http://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_GNU_PTH
30 # include <pth.h>
31 #endif
32
33 #include <assuan.h>
34
35 #include "scdaemon.h"
36 #include <ksba.h>
37 #include "app-common.h"
38 #include "apdu.h" /* Required for apdu_*_reader (). */
39 #include "exechelp.h"
40 #ifdef HAVE_LIBUSB
41 #include "ccid-driver.h"
42 #endif
43
44 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
45 #define MAXLEN_PIN 100
46
47 /* Maximum allowed size of key data as used in inquiries. */
48 #define MAXLEN_KEYDATA 4096
49
50
51 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
52
53
54 /* Macro to flag a removed card.  */
55 #define TEST_CARD_REMOVAL(c,r)                              \
56        do {                                                 \
57           int _r = (r);                                     \
58           if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \
59               || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED) \
60             update_card_removed ((c)->reader_slot, 1);      \
61        } while (0)
62
63 #define IS_LOCKED(c)                                                     \
64      (locked_session && locked_session != (c)->server_local              \
65       && (c)->reader_slot != -1 && locked_session->ctrl_backlink         \
66       && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot)
67
68
69 /* This structure is used to keep track of open readers (slots). */
70 struct slot_status_s 
71 {
72   int valid;  /* True if the other objects are valid. */
73   int slot;   /* Slot number of the reader or -1 if not open. */
74
75   int reset_failed; /* A reset failed. */
76
77   int any;    /* Flag indicating whether any status check has been
78                  done.  This is set once to indicate that the status
79                  tracking for the slot has been initialized.  */
80   unsigned int status;  /* Last status of the slot. */
81   unsigned int changed; /* Last change counter of teh slot. */
82 };
83
84
85 /* Data used to associate an Assuan context with local server data.
86    This object describes the local properties of one session.  */
87 struct server_local_s 
88 {
89   /* We keep a list of all active sessions with the anchor at
90      SESSION_LIST (see below).  This field is used for linking. */
91   struct server_local_s *next_session; 
92
93   /* This object is usually assigned to a CTRL object (which is
94      globally visible).  While enumerating all sessions we sometimes
95      need to access data of the CTRL object; thus we keep a
96      backpointer here. */
97   ctrl_t ctrl_backlink;
98
99   /* The Assuan context used by this session/server. */
100   assuan_context_t assuan_ctx;
101
102   int event_signal;        /* Or 0 if not used. */
103
104   /* True if the card has been removed and a reset is required to
105      continue operation. */
106   int card_removed;        
107 };
108
109
110 /* The table with information on all used slots.  FIXME: This is a
111    different slot number than the one used by the APDU layer, and
112    should be renamed.  */
113 static struct slot_status_s slot_table[10];
114
115
116 /* To keep track of all running sessions, we link all active server
117    contexts and the anchor in this variable.  */
118 static struct server_local_s *session_list;
119
120 /* If a session has been locked we store a link to its server object
121    in this variable. */
122 static struct server_local_s *locked_session;
123
124 /* While doing a reset we need to make sure that the ticker does not
125    call scd_update_reader_status_file while we are using it. */
126 static pth_mutex_t status_file_update_lock;
127
128 \f
129 /*-- Local prototypes --*/
130 static void update_reader_status_file (void);
131
132
133 \f
134
135 /* This function must be called once to initialize this module.  This
136    has to be done before a second thread is spawned.  We can't do the
137    static initialization because Pth emulation code might not be able
138    to do a static init; in particular, it is not possible for W32. */
139 void
140 initialize_module_command (void)
141 {
142   static int initialized;
143
144   if (!initialized)
145     {
146       if (pth_mutex_init (&status_file_update_lock))
147         initialized = 1;
148     }
149 }
150
151
152 /* Update the CARD_REMOVED element of all sessions using the reader
153    given by SLOT to VALUE  */
154 static void
155 update_card_removed (int slot, int value)
156 {
157   struct server_local_s *sl;
158
159   for (sl=session_list; sl; sl = sl->next_session)
160     if (sl->ctrl_backlink
161         && sl->ctrl_backlink->reader_slot == slot)
162       {
163         sl->card_removed = value;
164       }
165   if (value)
166     application_notify_card_removed (slot);
167 }
168
169
170
171 /* Check whether the option NAME appears in LINE */
172 static int
173 has_option (const char *line, const char *name)
174 {
175   const char *s;
176   int n = strlen (name);
177
178   s = strstr (line, name);
179   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
180 }
181
182 /* Same as has_option but does only test for the name of the option
183    and ignores an argument, i.e. with NAME being "--hash" it would
184    return a pointer for "--hash" as well as for "--hash=foo".  If
185    thhere is no such option NULL is returned.  The pointer returned
186    points right behind the option name, this may be an equal sign, Nul
187    or a space.  */
188 static const char *
189 has_option_name (const char *line, const char *name)
190 {
191   const char *s;
192   int n = strlen (name);
193
194   s = strstr (line, name);
195   return (s && (s == line || spacep (s-1))
196           && (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL;
197 }
198
199
200 /* Skip over options.  It is assumed that leading spaces have been
201    removed (this is the case for lines passed to a handler from
202    assuan).  Blanks after the options are also removed. */
203 static char *
204 skip_options (char *line)
205 {
206   while ( *line == '-' && line[1] == '-' )
207     {
208       while (*line && !spacep (line))
209         line++;
210       while (spacep (line))
211         line++;
212     }
213   return line;
214 }
215
216
217
218 /* Convert the STRING into a newly allocated buffer while translating
219    the hex numbers.  Stops at the first invalid character.  Blanks and
220    colons are allowed to separate the hex digits.  Returns NULL on
221    error or a newly malloced buffer and its length in LENGTH.  */
222 static unsigned char *
223 hex_to_buffer (const char *string, size_t *r_length)
224 {
225   unsigned char *buffer;
226   const char *s;
227   size_t n;
228
229   buffer = xtrymalloc (strlen (string)+1);
230   if (!buffer)
231     return NULL;
232   for (s=string, n=0; *s; s++)
233     {
234       if (spacep (s) || *s == ':') 
235         continue;
236       if (hexdigitp (s) && hexdigitp (s+1))
237         {
238           buffer[n++] = xtoi_2 (s);
239           s++;
240         }
241       else
242         break;
243     }
244   *r_length = n;
245   return buffer;
246 }
247
248
249
250 /* Reset the card and free the application context.  With SEND_RESET
251    set to true actually send a RESET to the reader. */
252 static void
253 do_reset (ctrl_t ctrl, int send_reset)
254 {
255   int slot = ctrl->reader_slot;
256
257   if (!(slot == -1 || (slot >= 0 && slot < DIM(slot_table))))
258     BUG ();
259
260   if (ctrl->app_ctx)
261     {
262       release_application (ctrl->app_ctx);
263       ctrl->app_ctx = NULL;
264     }
265
266   if (slot != -1 && send_reset && !IS_LOCKED (ctrl) )
267     {
268       if (apdu_reset (slot)) 
269         {
270           slot_table[slot].reset_failed = 1;
271         }
272     }
273
274   /* If we hold a lock, unlock now. */
275   if (locked_session && ctrl->server_local == locked_session)
276     {
277       locked_session = NULL;
278       log_info ("implicitly unlocking due to RESET\n");
279     }
280
281   /* Reset card removed flag for the current reader.  We need to take
282      the lock here so that the ticker thread won't concurrently try to
283      update the file.  Note that the update function will set the card
284      removed flag and we will later reset it - not a particualar nice
285      way of implementing it but it works. */
286   if (!pth_mutex_acquire (&status_file_update_lock, 0, NULL))
287     {
288       log_error ("failed to acquire status_fle_update lock\n");
289       ctrl->reader_slot = -1;
290       return;
291     }
292   update_reader_status_file ();
293   update_card_removed (slot, 0);
294   if (!pth_mutex_release (&status_file_update_lock))
295     log_error ("failed to release status_file_update lock\n");
296
297   /* Do this last, so that update_card_removed does its job.  */
298   ctrl->reader_slot = -1;
299 }
300
301 \f
302 static void
303 reset_notify (assuan_context_t ctx)
304 {
305   ctrl_t ctrl = assuan_get_pointer (ctx); 
306
307   do_reset (ctrl, 1);
308 }
309
310
311 static int
312 option_handler (assuan_context_t ctx, const char *key, const char *value)
313 {
314   ctrl_t ctrl = assuan_get_pointer (ctx);
315
316   if (!strcmp (key, "event-signal"))
317     {
318       /* A value of 0 is allowed to reset the event signal. */
319       int i = *value? atoi (value) : -1;
320       if (i < 0)
321         return gpg_error (GPG_ERR_ASS_PARAMETER);
322       ctrl->server_local->event_signal = i;
323     }
324
325  return 0;
326 }
327
328
329 /* Return the slot of the current reader or open the reader if no
330    other sessions are using a reader.  Note, that we currently support
331    only one reader but most of the code (except for this function)
332    should be able to cope with several readers.  */
333 static int
334 get_reader_slot (void)
335 {
336   struct slot_status_s *ss;
337
338   ss = &slot_table[0]; /* One reader for now. */
339
340   /* Initialize the item if needed. */
341   if (!ss->valid)
342     {
343       ss->slot = -1;
344       ss->valid = 1;
345     }
346
347   /* Try to open the reader. */
348   if (ss->slot == -1)
349     ss->slot = apdu_open_reader (opt.reader_port);
350
351   /* Return the slot_table index.  */
352   return 0;
353 }
354
355 /* If the card has not yet been opened, do it.  Note that this
356    function returns an Assuan error, so don't map the error a second
357    time.  */
358 static assuan_error_t
359 open_card (ctrl_t ctrl, const char *apptype)
360 {
361   gpg_error_t err;
362   int slot;
363
364   /* If we ever got a card not present error code, return that.  Only
365      the SERIALNO command and a reset are able to clear from that
366      state. */
367   if (ctrl->server_local->card_removed)
368     return gpg_error (GPG_ERR_CARD_REMOVED);
369
370   if ( IS_LOCKED (ctrl) )
371     return gpg_error (GPG_ERR_LOCKED);
372
373   if (ctrl->app_ctx)
374     {
375       /* Already initialized for one specific application.  Need to
376          check that the client didn't requested a specific application
377          different from the one in use. */
378       return check_application_conflict (ctrl, apptype);
379     }
380
381   if (ctrl->reader_slot != -1)
382     slot = ctrl->reader_slot;
383   else
384     slot = get_reader_slot ();
385   ctrl->reader_slot = slot;
386   if (slot == -1)
387     err = gpg_error (GPG_ERR_CARD);
388   else
389     err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
390
391   TEST_CARD_REMOVAL (ctrl, err);
392   return err;
393 }
394
395
396 /* Do the percent and plus/space unescaping in place and return the
397    length of the valid buffer. */
398 static size_t
399 percent_plus_unescape (unsigned char *string)
400 {
401   unsigned char *p = string;
402   size_t n = 0;
403
404   while (*string)
405     {
406       if (*string == '%' && string[1] && string[2])
407         { 
408           string++;
409           *p++ = xtoi_2 (string);
410           n++;
411           string+= 2;
412         }
413       else if (*string == '+')
414         {
415           *p++ = ' ';
416           n++;
417           string++;
418         }
419       else
420         {
421           *p++ = *string++;
422           n++;
423         }
424     }
425
426   return n;
427 }
428
429
430
431 /* SERIALNO [APPTYPE] 
432
433    Return the serial number of the card using a status reponse.  This
434    functon should be used to check for the presence of a card.
435
436    If APPTYPE is given, an application of that type is selected and an
437    error is returned if the application is not supported or available.
438    The default is to auto-select the application using a hardwired
439    preference system.  Note, that a future extension to this function
440    may allow to specify a list and order of applications to try.
441
442    This function is special in that it can be used to reset the card.
443    Most other functions will return an error when a card change has
444    been detected and the use of this function is therefore required.
445
446    Background: We want to keep the client clear of handling card
447    changes between operations; i.e. the client can assume that all
448    operations are done on the same card unless he calls this function.
449  */
450 static int
451 cmd_serialno (assuan_context_t ctx, char *line)
452 {
453   ctrl_t ctrl = assuan_get_pointer (ctx);
454   int rc = 0;
455   char *serial_and_stamp;
456   char *serial;
457   time_t stamp;
458
459   /* Clear the remove flag so that the open_card is able to reread it.  */
460   if (ctrl->server_local->card_removed)
461     {
462       if ( IS_LOCKED (ctrl) )
463         return gpg_error (GPG_ERR_LOCKED);
464       do_reset (ctrl, 1);
465     }
466
467   if ((rc = open_card (ctrl, *line? line:NULL)))
468     return rc;
469
470   rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
471   if (rc)
472     return rc;
473
474   rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
475   xfree (serial);
476   if (rc < 0)
477     return out_of_core ();
478   rc = 0;
479   assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
480   free (serial_and_stamp);
481   return 0;
482 }
483
484
485
486
487 /* LEARN [--force]
488
489    Learn all useful information of the currently inserted card.  When
490    used without the force options, the command might do an INQUIRE
491    like this:
492
493       INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>
494
495    The client should just send an "END" if the processing should go on
496    or a "CANCEL" to force the function to terminate with a Cancel
497    error message.  The response of this command is a list of status
498    lines formatted as this:
499
500      S APPTYPE <apptype>
501
502    This returns the type of the application, currently the strings:
503
504        P15     = PKCS-15 structure used
505        DINSIG  = DIN SIG
506        OPENPGP = OpenPGP card
507  
508    are implemented.  These strings are aliases for the AID
509
510      S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
511
512    If there is no certificate yet stored on the card a single "X" is
513    returned as the keygrip.  In addition to the keypair info, information
514    about all certificates stored on the card is also returned:
515
516      S CERTINFO <certtype> <hexstring_with_id>
517
518    Where CERTTYPE is a number indicating the type of certificate:
519       0   := Unknown
520       100 := Regular X.509 cert
521       101 := Trusted X.509 cert
522       102 := Useful X.509 cert
523       110 := Root CA cert (DINSIG)
524
525    For certain cards, more information will be returned:
526
527      S KEY-FPR <no> <hexstring>
528
529    For OpenPGP cards this returns the stored fingerprints of the
530    keys. This can be used check whether a key is available on the
531    card.  NO may be 1, 2 or 3.
532
533      S CA-FPR <no> <hexstring>
534
535    Similar to above, these are the fingerprints of keys assumed to be
536    ultimately trusted.
537
538      S DISP-NAME <name_of_card_holder>
539
540    The name of the card holder as stored on the card; percent
541    escaping takes place, spaces are encoded as '+'
542
543      S PUBKEY-URL <url>
544
545    The URL to be used for locating the entire public key.
546      
547    Note, that this function may be even be used on a locked card.
548 */
549 static int
550 cmd_learn (assuan_context_t ctx, char *line)
551 {
552   ctrl_t ctrl = assuan_get_pointer (ctx);
553   int rc = 0;
554
555   if ((rc = open_card (ctrl, NULL)))
556     return rc;
557
558   /* Unless the force option is used we try a shortcut by identifying
559      the card using a serial number and inquiring the client with
560      that. The client may choose to cancel the operation if he already
561      knows about this card */
562   {
563     char *serial_and_stamp;
564     char *serial;
565     time_t stamp;
566
567     rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
568     if (rc)
569       return rc;
570     rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
571     xfree (serial);
572     if (rc < 0)
573       return out_of_core ();
574     rc = 0;
575     assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
576
577     if (!has_option (line, "--force"))
578       {
579         char *command;
580
581         rc = asprintf (&command, "KNOWNCARDP %s", serial_and_stamp);
582         if (rc < 0)
583           {
584             free (serial_and_stamp);
585             return out_of_core ();
586           }
587         rc = 0;
588         rc = assuan_inquire (ctx, command, NULL, NULL, 0); 
589         free (command);  /* (must use standard free here) */
590         if (rc)
591           {
592             if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
593               log_error ("inquire KNOWNCARDP failed: %s\n",
594                          gpg_strerror (rc));
595             free (serial_and_stamp);
596             return rc; 
597           }
598         /* not canceled, so we have to proceeed */
599       }
600     free (serial_and_stamp);
601   }
602
603   /* Let the application print out its collection of useful status
604      information. */
605   if (!rc)
606     rc = app_write_learn_status (ctrl->app_ctx, ctrl);
607
608   TEST_CARD_REMOVAL (ctrl, rc);
609   return rc;
610 }
611
612
613 \f
614 /* READCERT <hexified_certid>
615
616    Note, that this function may even be used on a locked card.
617  */
618 static int
619 cmd_readcert (assuan_context_t ctx, char *line)
620 {
621   ctrl_t ctrl = assuan_get_pointer (ctx);
622   int rc;
623   unsigned char *cert;
624   size_t ncert;
625
626   if ((rc = open_card (ctrl, NULL)))
627     return rc;
628
629   line = xstrdup (line); /* Need a copy of the line. */
630   rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
631   if (rc)
632     log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
633   xfree (line);
634   line = NULL;
635   if (!rc)
636     {
637       rc = assuan_send_data (ctx, cert, ncert);
638       xfree (cert);
639       if (rc)
640         return rc;
641     }
642
643   TEST_CARD_REMOVAL (ctrl, rc);
644   return rc;
645 }
646
647
648 /* READKEY <keyid>
649
650    Return the public key for the given cert or key ID as an standard
651    S-Expression.
652
653    Note, that this function may even be used on a locked card.
654   */
655 static int
656 cmd_readkey (assuan_context_t ctx, char *line)
657 {
658   ctrl_t ctrl = assuan_get_pointer (ctx);
659   int rc;
660   unsigned char *cert = NULL;
661   size_t ncert, n;
662   ksba_cert_t kc = NULL;
663   ksba_sexp_t p;
664   unsigned char *pk;
665   size_t pklen;
666
667   if ((rc = open_card (ctrl, NULL)))
668     return rc;
669
670   line = xstrdup (line); /* Need a copy of the line. */
671   /* If the application supports the READKEY function we use that.
672      Otherwise we use the old way by extracting it from the
673      certificate.  */
674   rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen);
675   if (!rc)
676     { /* Yeah, got that key - send it back.  */
677       rc = assuan_send_data (ctx, pk, pklen);
678       xfree (pk);
679       xfree (line);
680       line = NULL;
681       goto leave;
682     }
683
684   if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
685     log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
686   else  
687     {
688       rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
689       if (rc)
690         log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
691     }
692   xfree (line);
693   line = NULL;
694   if (rc)
695     goto leave;
696       
697   rc = ksba_cert_new (&kc);
698   if (rc)
699     {
700       xfree (cert);
701       goto leave;
702     }
703   rc = ksba_cert_init_from_mem (kc, cert, ncert);
704   if (rc)
705     {
706       log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
707       goto leave;
708     }
709
710   p = ksba_cert_get_public_key (kc);
711   if (!p)
712     {
713       rc = gpg_error (GPG_ERR_NO_PUBKEY);
714       goto leave;
715     }
716
717   n = gcry_sexp_canon_len (p, 0, NULL, NULL);
718   rc = assuan_send_data (ctx, p, n);
719   xfree (p);
720
721
722  leave:
723   ksba_cert_release (kc);
724   xfree (cert);
725   TEST_CARD_REMOVAL (ctrl, rc);
726   return rc;
727 }
728
729
730 \f
731
732 /* SETDATA <hexstring> 
733
734    The client should use this command to tell us the data he want to
735    sign.  */
736 static int
737 cmd_setdata (assuan_context_t ctx, char *line)
738 {
739   ctrl_t ctrl = assuan_get_pointer (ctx);
740   int n;
741   char *p;
742   unsigned char *buf;
743
744   if (locked_session && locked_session != ctrl->server_local)
745     return gpg_error (GPG_ERR_LOCKED);
746
747   /* Parse the hexstring. */
748   for (p=line,n=0; hexdigitp (p); p++, n++)
749     ;
750   if (*p)
751     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
752   if (!n)
753     return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
754   if ((n&1))
755     return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
756   n /= 2;
757   buf = xtrymalloc (n);
758   if (!buf)
759     return out_of_core ();
760
761   ctrl->in_data.value = buf;
762   ctrl->in_data.valuelen = n;
763   for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++)
764     buf[n] = xtoi_2 (p);
765   return 0;
766 }
767
768
769
770 static gpg_error_t 
771 pin_cb (void *opaque, const char *info, char **retstr)
772 {
773   assuan_context_t ctx = opaque;
774   char *command;
775   int rc;
776   unsigned char *value;
777   size_t valuelen;
778
779   if (!retstr)
780     {
781       /* We prompt for keypad entry.  To make sure that the popup has
782          been show we use an inquire and not just a status message.
783          We ignore any value returned.  */
784       if (info)
785         {
786           log_debug ("prompting for keypad entry '%s'\n", info);
787           rc = asprintf (&command, "POPUPKEYPADPROMPT %s", info);
788           if (rc < 0)
789             return gpg_error (gpg_err_code_from_errno (errno));
790           rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); 
791           free (command);  
792         }
793       else
794         {
795           log_debug ("dismiss keypad entry prompt\n");
796           rc = assuan_inquire (ctx, "DISMISSKEYPADPROMPT",
797                                &value, &valuelen, MAXLEN_PIN); 
798         }
799       if (!rc)
800         xfree (value);
801       return rc;
802     }
803
804   *retstr = NULL;
805   log_debug ("asking for PIN '%s'\n", info);
806
807   rc = asprintf (&command, "NEEDPIN %s", info);
808   if (rc < 0)
809     return gpg_error (gpg_err_code_from_errno (errno));
810
811   /* Fixme: Write an inquire function which returns the result in
812      secure memory and check all further handling of the PIN. */
813   rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); 
814   free (command);  
815   if (rc)
816     return rc;
817
818   if (!valuelen || value[valuelen-1])
819     {
820       /* We require that the returned value is an UTF-8 string */
821       xfree (value);
822       return gpg_error (GPG_ERR_INV_RESPONSE);
823     }
824   *retstr = (char*)value;
825   return 0;
826 }
827
828
829 /* PKSIGN [--hash=[rmd160|sha1|md5]] <hexified_id>
830
831    The --hash option is optional; the default is SHA1.
832
833  */
834 static int
835 cmd_pksign (assuan_context_t ctx, char *line)
836 {
837   ctrl_t ctrl = assuan_get_pointer (ctx);
838   int rc;
839   unsigned char *outdata;
840   size_t outdatalen;
841   char *keyidstr;
842   int hash_algo;
843
844   if (has_option (line, "--hash=rmd160"))
845     hash_algo = GCRY_MD_RMD160;
846   else if (has_option (line, "--hash=sha1"))
847     hash_algo = GCRY_MD_SHA1;
848   else if (has_option (line, "--hash=md5"))
849     hash_algo = GCRY_MD_MD5;
850   else if (!strstr (line, "--"))
851     hash_algo = GCRY_MD_SHA1; 
852   else
853     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
854   /* Skip over options. */
855   while ( *line == '-' && line[1] == '-' )
856     {
857       while (*line && !spacep (line))
858         line++;
859       while (spacep (line))
860         line++;
861     }
862
863   if ( IS_LOCKED (ctrl) )
864     return gpg_error (GPG_ERR_LOCKED);
865
866   if ((rc = open_card (ctrl, NULL)))
867     return rc;
868
869   /* We have to use a copy of the key ID because the function may use
870      the pin_cb which in turn uses the assuan line buffer and thus
871      overwriting the original line with the keyid */
872   keyidstr = xtrystrdup (line);
873   if (!keyidstr)
874     return out_of_core ();
875   
876   rc = app_sign (ctrl->app_ctx,
877                  keyidstr, hash_algo,
878                  pin_cb, ctx,
879                  ctrl->in_data.value, ctrl->in_data.valuelen,
880                  &outdata, &outdatalen);
881
882   xfree (keyidstr);
883   if (rc)
884     {
885       log_error ("card_sign failed: %s\n", gpg_strerror (rc));
886     }
887   else
888     {
889       rc = assuan_send_data (ctx, outdata, outdatalen);
890       xfree (outdata);
891       if (rc)
892         return rc; /* that is already an assuan error code */
893     }
894
895   TEST_CARD_REMOVAL (ctrl, rc);
896   return rc;
897 }
898
899 /* PKAUTH <hexified_id>
900
901  */
902 static int
903 cmd_pkauth (assuan_context_t ctx, char *line)
904 {
905   ctrl_t ctrl = assuan_get_pointer (ctx);
906   int rc;
907   unsigned char *outdata;
908   size_t outdatalen;
909   char *keyidstr;
910
911   if ( IS_LOCKED (ctrl) )
912     return gpg_error (GPG_ERR_LOCKED);
913
914   if ((rc = open_card (ctrl, NULL)))
915     return rc;
916
917   if (!ctrl->app_ctx)
918     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
919
920  /* We have to use a copy of the key ID because the function may use
921      the pin_cb which in turn uses the assuan line buffer and thus
922      overwriting the original line with the keyid */
923   keyidstr = xtrystrdup (line);
924   if (!keyidstr)
925     return out_of_core ();
926   
927   rc = app_auth (ctrl->app_ctx,
928                  keyidstr,
929                  pin_cb, ctx,
930                  ctrl->in_data.value, ctrl->in_data.valuelen,
931                  &outdata, &outdatalen);
932   xfree (keyidstr);
933   if (rc)
934     {
935       log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc));
936     }
937   else
938     {
939       rc = assuan_send_data (ctx, outdata, outdatalen);
940       xfree (outdata);
941       if (rc)
942         return rc; /* that is already an assuan error code */
943     }
944
945   TEST_CARD_REMOVAL (ctrl, rc);
946   return rc;
947 }
948
949 /* PKDECRYPT <hexified_id>
950
951  */
952 static int
953 cmd_pkdecrypt (assuan_context_t ctx, char *line)
954 {
955   ctrl_t ctrl = assuan_get_pointer (ctx);
956   int rc;
957   unsigned char *outdata;
958   size_t outdatalen;
959   char *keyidstr;
960
961   if ( IS_LOCKED (ctrl) )
962     return gpg_error (GPG_ERR_LOCKED);
963
964   if ((rc = open_card (ctrl, NULL)))
965     return rc;
966
967   keyidstr = xtrystrdup (line);
968   if (!keyidstr)
969     return out_of_core ();
970   rc = app_decipher (ctrl->app_ctx,
971                      keyidstr, 
972                      pin_cb, ctx,
973                      ctrl->in_data.value, ctrl->in_data.valuelen,
974                      &outdata, &outdatalen);
975
976   xfree (keyidstr);
977   if (rc)
978     {
979       log_error ("card_create_signature failed: %s\n", gpg_strerror (rc));
980     }
981   else
982     {
983       rc = assuan_send_data (ctx, outdata, outdatalen);
984       xfree (outdata);
985       if (rc)
986         return rc; /* that is already an assuan error code */
987     }
988
989   TEST_CARD_REMOVAL (ctrl, rc);
990   return rc;
991 }
992
993
994 /* GETATTR <name>
995
996    This command is used to retrieve data from a smartcard.  The
997    allowed names depend on the currently selected smartcard
998    application.  NAME must be percent and '+' escaped.  The value is
999    returned through status message, see the LEARN command for details.
1000
1001    However, the current implementation assumes that Name is not escaped;
1002    this works as long as noone uses arbitrary escaping. 
1003  
1004    Note, that this function may even be used on a locked card.
1005 */
1006 static int
1007 cmd_getattr (assuan_context_t ctx, char *line)
1008 {
1009   ctrl_t ctrl = assuan_get_pointer (ctx);
1010   int rc;
1011   const char *keyword;
1012
1013   if ((rc = open_card (ctrl, NULL)))
1014     return rc;
1015
1016   keyword = line;
1017   for (; *line && !spacep (line); line++)
1018     ;
1019   if (*line)
1020       *line++ = 0;
1021
1022   /* (We ignore any garbage for now.) */
1023
1024   /* FIXME: Applications should not return sensitive data if the card
1025      is locked.  */
1026   rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
1027
1028   TEST_CARD_REMOVAL (ctrl, rc);
1029   return rc;
1030 }
1031
1032
1033 /* SETATTR <name> <value> 
1034
1035    This command is used to store data on a a smartcard.  The allowed
1036    names and values are depend on the currently selected smartcard
1037    application.  NAME and VALUE must be percent and '+' escaped.
1038
1039    However, the curent implementation assumes that Name is not escaped;
1040    this works as long as noone uses arbitrary escaping. 
1041  
1042    A PIN will be requested for most NAMEs.  See the corresponding
1043    setattr function of the actually used application (app-*.c) for
1044    details.  */
1045 static int
1046 cmd_setattr (assuan_context_t ctx, char *orig_line)
1047 {
1048   ctrl_t ctrl = assuan_get_pointer (ctx);
1049   int rc;
1050   char *keyword;
1051   int keywordlen;
1052   size_t nbytes;
1053   char *line, *linebuf;
1054
1055   if ( IS_LOCKED (ctrl) )
1056     return gpg_error (GPG_ERR_LOCKED);
1057
1058   if ((rc = open_card (ctrl, NULL)))
1059     return rc;
1060
1061   /* We need to use a copy of LINE, because PIN_CB uses the same
1062      context and thus reuses the Assuan provided LINE. */
1063   line = linebuf = xtrystrdup (orig_line);
1064   if (!line)
1065     return out_of_core ();
1066
1067   keyword = line;
1068   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1069     ;
1070   if (*line)
1071       *line++ = 0;
1072   while (spacep (line))
1073     line++;
1074   nbytes = percent_plus_unescape ((unsigned char*)line);
1075
1076   rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx,
1077                     (const unsigned char*)line, nbytes);
1078   xfree (linebuf);
1079
1080   TEST_CARD_REMOVAL (ctrl, rc);
1081   return rc;
1082 }
1083
1084
1085
1086 /* WRITEKEY [--force] <keyid> 
1087
1088    This command is used to store a secret key on a a smartcard.  The
1089    allowed keyids depend on the currently selected smartcard
1090    application. The actual keydata is requested using the inquiry
1091    "KETDATA" and need to be provided without any protection.  With
1092    --force set an existing key under this KEYID will get overwritten.
1093    The keydata is expected to be the usual canonical encoded
1094    S-expression.
1095
1096    A PIN will be requested for most NAMEs.  See the corresponding
1097    writekey function of the actually used application (app-*.c) for
1098    details.  */
1099 static int
1100 cmd_writekey (assuan_context_t ctx, char *line)
1101 {
1102   ctrl_t ctrl = assuan_get_pointer (ctx);
1103   int rc;
1104   char *keyid;
1105   int force = has_option (line, "--force");
1106   unsigned char *keydata;
1107   size_t keydatalen;
1108
1109   if ( IS_LOCKED (ctrl) )
1110     return gpg_error (GPG_ERR_LOCKED);
1111
1112   /* Skip over options. */
1113   while ( *line == '-' && line[1] == '-' )
1114     {
1115       while (*line && !spacep (line))
1116         line++;
1117       while (spacep (line))
1118         line++;
1119     }
1120   if (!*line)
1121     return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1122   keyid = line;
1123   while (*line && !spacep (line))
1124     line++;
1125   *line = 0;
1126
1127   if ((rc = open_card (ctrl, NULL)))
1128     return rc;
1129
1130   if (!ctrl->app_ctx)
1131     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1132
1133   keyid = xtrystrdup (keyid);
1134   if (!keyid)
1135     return out_of_core ();
1136
1137   /* Now get the actual keydata. */
1138   assuan_begin_confidential (ctx);
1139   rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1140   assuan_end_confidential (ctx);
1141   if (rc)
1142     {
1143       xfree (keyid);
1144       return rc;
1145     }
1146
1147   /* Write the key to the card. */
1148   rc = app_writekey (ctrl->app_ctx, ctrl, keyid, force? 1:0,
1149                      pin_cb, ctx, keydata, keydatalen);
1150   xfree (keyid);
1151   xfree (keydata);
1152
1153   TEST_CARD_REMOVAL (ctrl, rc);
1154   return rc;
1155 }
1156
1157
1158
1159 /* GENKEY [--force] [--timestamp=<isodate>] <no>
1160
1161    Generate a key on-card identified by NO, which is application
1162    specific.  Return values are application specific.  For OpenPGP
1163    cards 2 status lines are returned:
1164
1165      S KEY-FPR  <hexstring>
1166      S KEY-CREATED-AT <seconds_since_epoch>
1167      S KEY-DATA [p|n] <hexdata>
1168      
1169    --force is required to overwrite an already existing key.  The
1170    KEY-CREATED-AT is required for further processing because it is
1171    part of the hashed key material for the fingerprint.
1172
1173    If --timestamp is given an OpenPGP key will be created using this
1174    value.  The value needs to be in ISO Format; e.g.
1175    "--timestamp=20030316T120000" and after 1970-01-01 00:00:00.
1176
1177    The public part of the key can also later be retrieved using the
1178    READKEY command.
1179
1180  */
1181 static int
1182 cmd_genkey (assuan_context_t ctx, char *line)
1183 {
1184   ctrl_t ctrl = assuan_get_pointer (ctx);
1185   int rc;
1186   char *keyno;
1187   int force;
1188   const char *s;
1189   time_t timestamp;
1190
1191   if ( IS_LOCKED (ctrl) )
1192     return gpg_error (GPG_ERR_LOCKED);
1193
1194   force = has_option (line, "--force");
1195
1196   if ((s=has_option_name (line, "--timestamp")))
1197     {
1198       if (*s != '=')
1199         return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1200       timestamp = isotime2epoch (s+1);
1201       if (timestamp < 1)
1202         return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1203     }
1204   else
1205     timestamp = 0;
1206
1207
1208   line = skip_options (line);
1209   if (!*line)
1210     return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1211   keyno = line;
1212   while (*line && !spacep (line))
1213     line++;
1214   *line = 0;
1215
1216   if ((rc = open_card (ctrl, NULL)))
1217     return rc;
1218
1219   if (!ctrl->app_ctx)
1220     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1221
1222   keyno = xtrystrdup (keyno);
1223   if (!keyno)
1224     return out_of_core ();
1225   rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
1226                    timestamp, pin_cb, ctx);
1227   xfree (keyno);
1228
1229   TEST_CARD_REMOVAL (ctrl, rc);
1230   return rc;
1231 }
1232
1233
1234 /* RANDOM <nbytes>
1235
1236    Get NBYTES of random from the card and send them back as data. 
1237
1238    Note, that this function may be even be used on a locked card.
1239 */
1240 static int
1241 cmd_random (assuan_context_t ctx, char *line)
1242 {
1243   ctrl_t ctrl = assuan_get_pointer (ctx);
1244   int rc;
1245   size_t nbytes;
1246   unsigned char *buffer;
1247
1248   if (!*line)
1249     return set_error (GPG_ERR_ASS_PARAMETER, "number of requested bytes missing");
1250   nbytes = strtoul (line, NULL, 0);
1251
1252   if ((rc = open_card (ctrl, NULL)))
1253     return rc;
1254
1255   if (!ctrl->app_ctx)
1256     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1257
1258   buffer = xtrymalloc (nbytes);
1259   if (!buffer)
1260     return out_of_core ();
1261
1262   rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
1263   if (!rc)
1264     {
1265       rc = assuan_send_data (ctx, buffer, nbytes);
1266       xfree (buffer);
1267       return rc; /* that is already an assuan error code */
1268     }
1269   xfree (buffer);
1270
1271   TEST_CARD_REMOVAL (ctrl, rc);
1272   return rc;
1273 }
1274
1275 \f
1276 /* PASSWD [--reset] <chvno>
1277   
1278    Change the PIN or reset the retry counter of the card holder
1279    verfication vector CHVNO. */
1280 static int
1281 cmd_passwd (assuan_context_t ctx, char *line)
1282 {
1283   ctrl_t ctrl = assuan_get_pointer (ctx);
1284   int rc;
1285   char *chvnostr;
1286   int reset_mode = has_option (line, "--reset");
1287
1288   if ( IS_LOCKED (ctrl) )
1289     return gpg_error (GPG_ERR_LOCKED);
1290
1291   /* Skip over options. */
1292   while (*line == '-' && line[1] == '-')
1293     {
1294       while (*line && !spacep (line))
1295         line++;
1296       while (spacep (line))
1297         line++;
1298     }
1299   if (!*line)
1300     return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1301   chvnostr = line;
1302   while (*line && !spacep (line))
1303     line++;
1304   *line = 0;
1305
1306   if ((rc = open_card (ctrl, NULL)))
1307     return rc;
1308
1309   if (!ctrl->app_ctx)
1310     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1311   
1312   chvnostr = xtrystrdup (chvnostr);
1313   if (!chvnostr)
1314     return out_of_core ();
1315   rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, reset_mode, pin_cb, ctx);
1316   if (rc)
1317     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1318   xfree (chvnostr);
1319
1320   TEST_CARD_REMOVAL (ctrl, rc);
1321   return rc;
1322 }
1323
1324
1325 /* CHECKPIN <idstr>
1326
1327    Perform a VERIFY operation without doing anything else.  This may
1328    be used to initialize a the PIN cache earlier to long lasting
1329    operations.  Its use is highly application dependent.
1330
1331    For OpenPGP:
1332
1333       Perform a simple verify operation for CHV1 and CHV2, so that
1334       further operations won't ask for CHV2 and it is possible to do a
1335       cheap check on the PIN: If there is something wrong with the PIN
1336       entry system, only the regular CHV will get blocked and not the
1337       dangerous CHV3.  IDSTR is the usual card's serial number in hex
1338       notation; an optional fingerprint part will get ignored.  There
1339       is however a special mode if the IDSTR is sffixed with the
1340       literal string "[CHV3]": In this case the Admin PIN is checked
1341       if and only if the retry counter is still at 3.
1342
1343  */
1344 static int
1345 cmd_checkpin (assuan_context_t ctx, char *line)
1346 {
1347   ctrl_t ctrl = assuan_get_pointer (ctx);
1348   int rc;
1349   char *keyidstr;
1350
1351   if ( IS_LOCKED (ctrl) )
1352     return gpg_error (GPG_ERR_LOCKED);
1353
1354   if ((rc = open_card (ctrl, NULL)))
1355     return rc;
1356
1357   if (!ctrl->app_ctx)
1358     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1359
1360   /* We have to use a copy of the key ID because the function may use
1361      the pin_cb which in turn uses the assuan line buffer and thus
1362      overwriting the original line with the keyid. */
1363   keyidstr = xtrystrdup (line);
1364   if (!keyidstr)
1365     return out_of_core ();
1366   
1367   rc = app_check_pin (ctrl->app_ctx,
1368                       keyidstr,
1369                       pin_cb, ctx);
1370   xfree (keyidstr);
1371   if (rc)
1372     log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1373
1374   TEST_CARD_REMOVAL (ctrl, rc);
1375   return rc;
1376 }
1377
1378
1379 /* LOCK [--wait]
1380
1381    Grant exclusive card access to this session.  Note that there is
1382    no lock counter used and a second lock from the same session will
1383    be ignored.  A single unlock (or RESET) unlocks the session.
1384    Return GPG_ERR_LOCKED if another session has locked the reader.
1385
1386    If the option --wait is given the command will wait until a
1387    lock has been released.
1388  */
1389 static int
1390 cmd_lock (assuan_context_t ctx, char *line)
1391 {
1392   ctrl_t ctrl = assuan_get_pointer (ctx);
1393   int rc = 0;
1394
1395  retry:
1396   if (locked_session)
1397     {
1398       if (locked_session != ctrl->server_local)
1399         rc = gpg_error (GPG_ERR_LOCKED);
1400     }
1401   else
1402     locked_session = ctrl->server_local;
1403
1404 #ifdef USE_GNU_PTH
1405   if (rc && has_option (line, "--wait"))
1406     {
1407       rc = 0;
1408       pth_sleep (1); /* Better implement an event mechanism. However,
1409                         for card operations this should be
1410                         sufficient. */
1411       /* FIXME: Need to check that the connection is still alive.
1412          This can be done by issuing status messages. */
1413       goto retry;
1414     }
1415 #endif /*USE_GNU_PTH*/
1416   
1417   if (rc)
1418     log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1419   return rc;
1420 }
1421
1422
1423 /* UNLOCK
1424
1425    Release exclusive card access.
1426  */
1427 static int
1428 cmd_unlock (assuan_context_t ctx, char *line)
1429 {
1430   ctrl_t ctrl = assuan_get_pointer (ctx);
1431   int rc = 0;
1432
1433   if (locked_session)
1434     {
1435       if (locked_session != ctrl->server_local)
1436         rc = gpg_error (GPG_ERR_LOCKED);
1437       else
1438         locked_session = NULL;
1439     }
1440   else
1441     rc = gpg_error (GPG_ERR_NOT_LOCKED);
1442
1443   if (rc)
1444     log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1445   return rc;
1446 }
1447
1448
1449 /* GETINFO <what>
1450
1451    Multi purpose command to return certain information.  
1452    Supported values of WHAT are:
1453
1454    version     - Return the version of the program.
1455
1456    socket_name - Return the name of the socket.
1457
1458    status - Return the status of the current slot (in the future, may
1459    also return the status of all slots).  The status is a list of
1460    one-character flags.  The following flags are currently defined:
1461      'u'  Usable card present.  This is the normal state during operation.
1462      'r'  Card removed.  A reset is necessary.
1463    These flags are exclusive.
1464
1465    reader_list - Return a list of detected card readers.  Does
1466                  currently only work with the internal CCID driver.
1467 */
1468
1469 static int
1470 cmd_getinfo (assuan_context_t ctx, char *line)
1471 {
1472   int rc = 0;
1473
1474   if (!strcmp (line, "version"))
1475     {
1476       const char *s = VERSION;
1477       rc = assuan_send_data (ctx, s, strlen (s));
1478     }
1479   else if (!strcmp (line, "socket_name"))
1480     {
1481       const char *s = scd_get_socket_name ();
1482
1483       if (s)
1484         rc = assuan_send_data (ctx, s, strlen (s));
1485       else
1486         rc = gpg_error (GPG_ERR_NO_DATA);
1487     }
1488   else if (!strcmp (line, "status"))
1489     {
1490       ctrl_t ctrl = assuan_get_pointer (ctx);
1491       int slot = ctrl->reader_slot;
1492       char flag = 'r';
1493
1494       if (!ctrl->server_local->card_removed && slot != -1)
1495         {
1496           struct slot_status_s *ss;
1497           
1498           if (!(slot >= 0 && slot < DIM(slot_table)))
1499             BUG ();
1500
1501           ss = &slot_table[slot];
1502
1503           if (!ss->valid)
1504             BUG ();
1505
1506           if (ss->any && (ss->status & 1))
1507             flag = 'u';
1508         }
1509       rc = assuan_send_data (ctx, &flag, 1);
1510     }
1511   else if (!strcmp (line, "reader_list"))
1512     {
1513 #ifdef HAVE_LIBUSB
1514       char *s = ccid_get_reader_list ();
1515 #else
1516       char *s = NULL;
1517 #endif
1518       
1519       if (s)
1520         rc = assuan_send_data (ctx, s, strlen (s));
1521       else
1522         rc = gpg_error (GPG_ERR_NO_DATA);
1523       xfree (s);
1524     }
1525   else
1526     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1527   return rc;
1528 }
1529
1530
1531 /* RESTART
1532
1533    Restart the current connection; this is a kind of warm reset.  It
1534    deletes the context used by this connection but does not send a
1535    RESET to the card.  Thus the card itself won't get reset. 
1536
1537    This is used by gpg-agent to reuse a primary pipe connection and
1538    may be used by clients to backup from a conflict in the serial
1539    command; i.e. to select another application. 
1540 */
1541
1542 static int
1543 cmd_restart (assuan_context_t ctx, char *line)
1544 {
1545   ctrl_t ctrl = assuan_get_pointer (ctx);
1546
1547   if (ctrl->app_ctx)
1548     {
1549       release_application (ctrl->app_ctx);
1550       ctrl->app_ctx = NULL;
1551     }
1552   if (locked_session && ctrl->server_local == locked_session)
1553     {
1554       locked_session = NULL;
1555       log_info ("implicitly unlocking due to RESTART\n");
1556     }
1557   return 0;
1558 }
1559
1560
1561 /* APDU [--atr] [--more] [hexstring]
1562
1563    Send an APDU to the current reader.  This command bypasses the high
1564    level functions and sends the data directly to the card.  HEXSTRING
1565    is expected to be a proper APDU.  If HEXSTRING is not given no
1566    commands are set to the card but the command will implictly check
1567    whether the card is ready for use. 
1568
1569    Using the option "--atr" returns the ATR of the card as a status
1570    message before any data like this:
1571      S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1
1572
1573    Using the option --more handles the card status word MORE_DATA
1574    (61xx) and concatenate all reponses to one block.
1575
1576  */
1577 static int
1578 cmd_apdu (assuan_context_t ctx, char *line)
1579 {
1580   ctrl_t ctrl = assuan_get_pointer (ctx);
1581   int rc;
1582   unsigned char *apdu;
1583   size_t apdulen;
1584   int with_atr;
1585   int handle_more;
1586
1587   with_atr = has_option (line, "--atr");
1588   handle_more = has_option (line, "--more");
1589
1590   /* Skip over options. */
1591   while ( *line == '-' && line[1] == '-' )
1592     {
1593       while (*line && !spacep (line))
1594         line++;
1595       while (spacep (line))
1596         line++;
1597     }
1598
1599   if ( IS_LOCKED (ctrl) )
1600     return gpg_error (GPG_ERR_LOCKED);
1601
1602   if ((rc = open_card (ctrl, NULL)))
1603     return rc;
1604
1605   if (with_atr)
1606     {
1607       unsigned char *atr;
1608       size_t atrlen;
1609       int i;
1610       char hexbuf[400];
1611       
1612       atr = apdu_get_atr (ctrl->reader_slot, &atrlen);
1613       if (!atr || atrlen > sizeof hexbuf - 2 )
1614         {
1615           rc = gpg_error (GPG_ERR_INV_CARD);
1616           goto leave;
1617         }
1618       for (i=0; i < atrlen; i++)
1619         sprintf (hexbuf+2*i, "%02X", atr[i]);
1620       xfree (atr);
1621       send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1622     }
1623
1624   apdu = hex_to_buffer (line, &apdulen);
1625   if (!apdu)
1626     {
1627       rc = gpg_error_from_syserror ();
1628       goto leave;
1629     }
1630   if (apdulen)
1631     {
1632       unsigned char *result = NULL;
1633       size_t resultlen;
1634
1635       rc = apdu_send_direct (ctrl->reader_slot, apdu, apdulen, handle_more,
1636                              &result, &resultlen);
1637       if (rc)
1638         log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1639       else
1640         {
1641           rc = assuan_send_data (ctx, result, resultlen);
1642           xfree (result);
1643         }
1644     }
1645   xfree (apdu);
1646
1647  leave:
1648   TEST_CARD_REMOVAL (ctrl, rc);
1649   return rc;
1650 }
1651
1652
1653
1654
1655 \f
1656 /* Tell the assuan library about our commands */
1657 static int
1658 register_commands (assuan_context_t ctx)
1659 {
1660   static struct {
1661     const char *name;
1662     int (*handler)(assuan_context_t, char *line);
1663   } table[] = {
1664     { "SERIALNO",     cmd_serialno },
1665     { "LEARN",        cmd_learn },
1666     { "READCERT",     cmd_readcert },
1667     { "READKEY",      cmd_readkey },
1668     { "SETDATA",      cmd_setdata },
1669     { "PKSIGN",       cmd_pksign },
1670     { "PKAUTH",       cmd_pkauth },
1671     { "PKDECRYPT",    cmd_pkdecrypt },
1672     { "INPUT",        NULL }, 
1673     { "OUTPUT",       NULL }, 
1674     { "GETATTR",      cmd_getattr },
1675     { "SETATTR",      cmd_setattr },
1676     { "WRITEKEY",     cmd_writekey },
1677     { "GENKEY",       cmd_genkey },
1678     { "RANDOM",       cmd_random },
1679     { "PASSWD",       cmd_passwd },
1680     { "CHECKPIN",     cmd_checkpin },
1681     { "LOCK",         cmd_lock },
1682     { "UNLOCK",       cmd_unlock },
1683     { "GETINFO",      cmd_getinfo },
1684     { "RESTART",      cmd_restart },
1685     { "APDU",         cmd_apdu },
1686     { NULL }
1687   };
1688   int i, rc;
1689
1690   for (i=0; table[i].name; i++)
1691     {
1692       rc = assuan_register_command (ctx, table[i].name, table[i].handler);
1693       if (rc)
1694         return rc;
1695     } 
1696   assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1697
1698   assuan_register_reset_notify (ctx, reset_notify);
1699   assuan_register_option_handler (ctx, option_handler);
1700   return 0;
1701 }
1702
1703
1704 /* Startup the server.  If FD is given as -1 this is simple pipe
1705    server, otherwise it is a regular server. */
1706 void
1707 scd_command_handler (ctrl_t ctrl, int fd)
1708 {
1709   int rc;
1710   assuan_context_t ctx;
1711   
1712   if (fd == -1)
1713     {
1714       int filedes[2];
1715
1716       filedes[0] = 0;
1717       filedes[1] = 1;
1718       rc = assuan_init_pipe_server (&ctx, filedes);
1719     }
1720   else
1721     {
1722       rc = assuan_init_socket_server_ext (&ctx, fd, 2);
1723     }
1724   if (rc)
1725     {
1726       log_error ("failed to initialize the server: %s\n",
1727                  gpg_strerror(rc));
1728       scd_exit (2);
1729     }
1730   rc = register_commands (ctx);
1731   if (rc)
1732     {
1733       log_error ("failed to register commands with Assuan: %s\n",
1734                  gpg_strerror(rc));
1735       scd_exit (2);
1736     }
1737   assuan_set_pointer (ctx, ctrl);
1738
1739   /* Allocate and initialize the server object.  Put it into the list
1740      of active sessions. */
1741   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
1742   ctrl->server_local->next_session = session_list;
1743   session_list = ctrl->server_local;
1744   ctrl->server_local->ctrl_backlink = ctrl;
1745   ctrl->server_local->assuan_ctx = ctx;
1746
1747   if (DBG_ASSUAN)
1748     assuan_set_log_stream (ctx, log_get_stream ());
1749
1750   /* We open the reader right at startup so that the ticker is able to
1751      update the status file. */
1752   if (ctrl->reader_slot == -1)
1753     {
1754       ctrl->reader_slot = get_reader_slot ();
1755     }
1756
1757   /* Command processing loop. */
1758   for (;;)
1759     {
1760       rc = assuan_accept (ctx);
1761       if (rc == -1)
1762         {
1763           break;
1764         }
1765       else if (rc)
1766         {
1767           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1768           break;
1769         }
1770       
1771       rc = assuan_process (ctx);
1772       if (rc)
1773         {
1774           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1775           continue;
1776         }
1777     }
1778
1779   /* Cleanup.  */
1780   do_reset (ctrl, 0); 
1781
1782   /* Release the server object.  */
1783   if (session_list == ctrl->server_local)
1784     session_list = ctrl->server_local->next_session;
1785   else
1786     {
1787       struct server_local_s *sl;
1788       
1789       for (sl=session_list; sl->next_session; sl = sl->next_session)
1790         if (sl->next_session == ctrl->server_local)
1791           break;
1792       if (!sl->next_session)
1793           BUG ();
1794       sl->next_session = ctrl->server_local->next_session;
1795     }
1796   xfree (ctrl->server_local);
1797   ctrl->server_local = NULL;
1798
1799   /* Release the Assuan context.  */
1800   assuan_deinit_server (ctx);
1801 }
1802
1803
1804 /* Send a line with status information via assuan and escape all given
1805    buffers. The variable elements are pairs of (char *, size_t),
1806    terminated with a (NULL, 0). */
1807 void
1808 send_status_info (ctrl_t ctrl, const char *keyword, ...)
1809 {
1810   va_list arg_ptr;
1811   const unsigned char *value;
1812   size_t valuelen;
1813   char buf[950], *p;
1814   size_t n;
1815   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1816   
1817   va_start (arg_ptr, keyword);
1818
1819   p = buf; 
1820   n = 0;
1821   while ( (value = va_arg (arg_ptr, const unsigned char *)) )
1822     {
1823       valuelen = va_arg (arg_ptr, size_t);
1824       if (!valuelen)
1825         continue; /* empty buffer */
1826       if (n)
1827         {
1828           *p++ = ' ';
1829           n++;
1830         }
1831       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
1832         {
1833           if (*value < ' ' || *value == '+')
1834             {
1835               sprintf (p, "%%%02X", *value);
1836               p += 3;
1837             }
1838           else if (*value == ' ')
1839             *p++ = '+';
1840           else
1841             *p++ = *value;
1842         }
1843     }
1844   *p = 0;
1845   assuan_write_status (ctx, keyword, buf);
1846
1847   va_end (arg_ptr);
1848 }
1849
1850
1851 /* This is the core of scd_update_reader_status_file but the caller
1852    needs to take care of the locking. */
1853 static void
1854 update_reader_status_file (void)
1855 {
1856   int idx;
1857   unsigned int status, changed;
1858
1859   /* Note, that we only try to get the status, because it does not
1860      make sense to wait here for a operation to complete.  If we are
1861      busy working with a card, delays in the status file update should
1862      be acceptable. */
1863   for (idx=0; idx < DIM(slot_table); idx++)
1864     {
1865       struct slot_status_s *ss = slot_table + idx;
1866
1867       if (!ss->valid || ss->slot == -1)
1868         continue; /* Not valid or reader not yet open. */
1869       
1870       if ( apdu_get_status (ss->slot, 0, &status, &changed) )
1871         continue; /* Get status failed. */
1872
1873       if (!ss->any || ss->status != status || ss->changed != changed )
1874         {
1875           char *fname;
1876           char templ[50];
1877           FILE *fp;
1878           struct server_local_s *sl;
1879
1880           log_info ("updating status of slot %d to 0x%04X\n",
1881                     ss->slot, status);
1882
1883           /* FIXME: Should this be IDX instead of ss->slot?  This
1884              depends on how client sessions will associate the reader
1885              status with their session.  */
1886           sprintf (templ, "reader_%d.status", ss->slot);
1887           fname = make_filename (opt.homedir, templ, NULL );
1888           fp = fopen (fname, "w");
1889           if (fp)
1890             {
1891               fprintf (fp, "%s\n",
1892                        (status & 1)? "USABLE":
1893                        (status & 4)? "ACTIVE":
1894                        (status & 2)? "PRESENT": "NOCARD");
1895               fclose (fp);
1896             }
1897           xfree (fname);
1898             
1899           /* If a status script is executable, run it. */
1900           {
1901             const char *args[9], *envs[2];
1902             char numbuf1[30], numbuf2[30], numbuf3[30];
1903             char *homestr, *envstr;
1904             gpg_error_t err;
1905             
1906             homestr = make_filename (opt.homedir, NULL);
1907             if (asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
1908               log_error ("out of core while building environment\n");
1909             else
1910               {
1911                 envs[0] = envstr;
1912                 envs[1] = NULL;
1913
1914                 sprintf (numbuf1, "%d", ss->slot);
1915                 sprintf (numbuf2, "0x%04X", ss->status);
1916                 sprintf (numbuf3, "0x%04X", status);
1917                 args[0] = "--reader-port";
1918                 args[1] = numbuf1; 
1919                 args[2] = "--old-code";
1920                 args[3] = numbuf2;  
1921                 args[4] = "--new-code";
1922                 args[5] = numbuf3; 
1923                 args[6] = "--status";
1924                 args[7] = ((status & 1)? "USABLE":
1925                            (status & 4)? "ACTIVE":
1926                            (status & 2)? "PRESENT": "NOCARD");
1927                 args[8] = NULL;  
1928
1929                 fname = make_filename (opt.homedir, "scd-event", NULL);
1930                 err = gnupg_spawn_process_detached (fname, args, envs);
1931                 if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
1932                   log_error ("failed to run event handler `%s': %s\n",
1933                              fname, gpg_strerror (err));
1934                 xfree (fname);
1935                 free (envstr);
1936               }
1937             xfree (homestr);
1938           }
1939
1940           /* Set the card removed flag for all current sessions.  We
1941              will set this on any card change because a reset or
1942              SERIALNO request must be done in any case.  */
1943           if (ss->any)
1944             update_card_removed (idx, 1);
1945           
1946           ss->any = 1;
1947           ss->status = status;
1948           ss->changed = changed;
1949
1950           /* Send a signal to all clients who applied for it.  */
1951           for (sl=session_list; sl; sl = sl->next_session)
1952             if (sl->event_signal && sl->assuan_ctx)
1953               {
1954                 pid_t pid = assuan_get_pid (sl->assuan_ctx);
1955                 int signo = sl->event_signal;
1956                 
1957                 log_info ("client pid is %d, sending signal %d\n",
1958                           pid, signo);
1959 #ifndef HAVE_W32_SYSTEM
1960                 if (pid != (pid_t)(-1) && pid && signo > 0)
1961                   kill (pid, signo);
1962 #endif
1963               }
1964
1965         }
1966     }
1967 }
1968
1969 /* This function is called by the ticker thread to check for changes
1970    of the reader stati.  It updates the reader status files and if
1971    requested by the caller also send a signal to the caller.  */
1972 void
1973 scd_update_reader_status_file (void)
1974 {
1975   if (!pth_mutex_acquire (&status_file_update_lock, 1, NULL))
1976     return; /* locked - give up. */
1977   update_reader_status_file ();
1978   if (!pth_mutex_release (&status_file_update_lock))
1979     log_error ("failed to release status_file_update lock\n");
1980 }