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