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