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