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