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