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