1 /* command.c - SCdaemon command handler
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3 * 2007, 2008 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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.
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.
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/>.
37 #include "app-common.h"
38 #include "apdu.h" /* Required for apdu_*_reader (). */
41 #include "ccid-driver.h"
44 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
45 #define MAXLEN_PIN 100
47 /* Maximum allowed size of key data as used in inquiries. */
48 #define MAXLEN_KEYDATA 4096
50 /* Maximum allowed size of certificate data as used in inquiries. */
51 #define MAXLEN_CERTDATA 16384
54 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
57 /* Macro to flag a removed card. */
58 #define TEST_CARD_REMOVAL(c,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); \
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)
72 /* This structure is used to keep track of open readers (slots). */
75 int valid; /* True if the other objects are valid. */
76 int slot; /* Slot number of the reader or -1 if not open. */
78 int reset_failed; /* A reset failed. */
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. */
88 /* Data used to associate an Assuan context with local server data.
89 This object describes the local properties of one session. */
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;
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
100 ctrl_t ctrl_backlink;
102 /* The Assuan context used by this session/server. */
103 assuan_context_t assuan_ctx;
105 #ifdef HAVE_W32_SYSTEM
106 unsigned long event_signal; /* Or 0 if not used. */
108 int event_signal; /* Or 0 if not used. */
111 /* True if the card has been removed and a reset is required to
112 continue operation. */
115 /* A disconnect command has been sent. */
116 int disconnect_allowed;
118 /* If set to true we will be terminate ourself at the end of the
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];
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;
135 /* If a session has been locked we store a link to its server object
137 static struct server_local_s *locked_session;
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;
144 /*-- Local prototypes --*/
145 static void update_reader_status_file (int set_card_removed_flag);
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. */
155 initialize_module_command (void)
157 static int initialized;
161 if (pth_mutex_init (&status_file_update_lock))
167 /* Update the CARD_REMOVED element of all sessions using the reader
168 given by SLOT to VALUE */
170 update_card_removed (int slot, int value)
172 struct server_local_s *sl;
174 for (sl=session_list; sl; sl = sl->next_session)
175 if (sl->ctrl_backlink
176 && sl->ctrl_backlink->reader_slot == slot)
178 sl->card_removed = value;
180 /* Let the card application layer know about the removal. */
182 application_notify_card_reset (slot);
187 /* Check whether the option NAME appears in LINE */
189 has_option (const char *line, const char *name)
192 int n = strlen (name);
194 s = strstr (line, name);
195 return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
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
205 has_option_name (const char *line, const char *name)
208 int n = strlen (name);
210 s = strstr (line, name);
211 return (s && (s == line || spacep (s-1))
212 && (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL;
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. */
220 skip_options (char *line)
222 while ( *line == '-' && line[1] == '-' )
224 while (*line && !spacep (line))
226 while (spacep (line))
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)
241 unsigned char *buffer;
245 buffer = xtrymalloc (strlen (string)+1);
248 for (s=string, n=0; *s; s++)
250 if (spacep (s) || *s == ':')
252 if (hexdigitp (s) && hexdigitp (s+1))
254 buffer[n++] = xtoi_2 (s);
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. */
270 do_reset (ctrl_t ctrl, int send_reset)
272 int slot = ctrl->reader_slot;
274 if (!(slot == -1 || (slot >= 0 && slot < DIM(slot_table))))
277 /* If there is an active application, release it. */
280 release_application (ctrl->app_ctx);
281 ctrl->app_ctx = NULL;
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) )
288 if (apdu_reset (slot))
290 slot_table[slot].reset_failed = 1;
292 application_notify_card_reset (slot);
295 /* If we hold a lock, unlock now. */
296 if (locked_session && ctrl->server_local == locked_session)
298 locked_session = NULL;
299 log_info ("implicitly unlocking due to RESET\n");
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
307 if (!pth_mutex_acquire (&status_file_update_lock, 0, NULL))
309 log_error ("failed to acquire status_fle_update lock\n");
310 ctrl->reader_slot = -1;
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");
318 /* Do this last, so that the update_card_removed above does its job. */
319 ctrl->reader_slot = -1;
324 reset_notify (assuan_context_t ctx)
326 ctrl_t ctrl = assuan_get_pointer (ctx);
333 option_handler (assuan_context_t ctx, const char *key, const char *value)
335 ctrl_t ctrl = assuan_get_pointer (ctx);
337 if (!strcmp (key, "event-signal"))
339 /* A value of 0 is allowed to reset the event signal. */
340 #ifdef HAVE_W32_SYSTEM
342 return gpg_error (GPG_ERR_ASS_PARAMETER);
343 ctrl->server_local->event_signal = strtoul (value, NULL, 16);
345 int i = *value? atoi (value) : -1;
347 return gpg_error (GPG_ERR_ASS_PARAMETER);
348 ctrl->server_local->event_signal = i;
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. */
361 get_reader_slot (void)
363 struct slot_status_s *ss;
365 ss = &slot_table[0]; /* One reader for now. */
367 /* Initialize the item if needed. */
374 /* Try to open the reader. */
376 ss->slot = apdu_open_reader (opt.reader_port);
378 /* Return the slot_table index. */
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
385 static assuan_error_t
386 open_card (ctrl_t ctrl, const char *apptype)
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
394 if (ctrl->server_local->card_removed)
395 return gpg_error (GPG_ERR_CARD_REMOVED);
397 if ( IS_LOCKED (ctrl) )
398 return gpg_error (GPG_ERR_LOCKED);
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);
408 if (ctrl->reader_slot != -1)
409 slot = ctrl->reader_slot;
411 slot = get_reader_slot ();
412 ctrl->reader_slot = slot;
414 err = gpg_error (GPG_ERR_CARD);
417 /* Fixme: We should move the apdu_connect call to
418 select_application. */
421 ctrl->server_local->disconnect_allowed = 0;
422 sw = apdu_connect (slot);
423 if (sw && sw != SW_HOST_ALREADY_CONNECTED)
425 if (sw == SW_HOST_NO_CARD)
426 err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
428 err = gpg_error (GPG_ERR_CARD);
431 err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
434 TEST_CARD_REMOVAL (ctrl, err);
439 /* Do the percent and plus/space unescaping in place and return the
440 length of the valid buffer. */
442 percent_plus_unescape (unsigned char *string)
444 unsigned char *p = string;
449 if (*string == '%' && string[1] && string[2])
452 *p++ = xtoi_2 (string);
456 else if (*string == '+')
474 /* SERIALNO [APPTYPE]
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.
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.
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.
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.
494 cmd_serialno (assuan_context_t ctx, char *line)
496 ctrl_t ctrl = assuan_get_pointer (ctx);
498 char *serial_and_stamp;
502 /* Clear the remove flag so that the open_card is able to reread it. */
503 if (ctrl->server_local->card_removed)
505 if ( IS_LOCKED (ctrl) )
506 return gpg_error (GPG_ERR_LOCKED);
510 if ((rc = open_card (ctrl, *line? line:NULL)))
513 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
517 rc = estream_asprintf (&serial_and_stamp, "%s %lu",
518 serial, (unsigned long)stamp);
521 return out_of_core ();
523 assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
524 xfree (serial_and_stamp);
533 Learn all useful information of the currently inserted card. When
534 used without the force options, the command might do an INQUIRE
537 INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>
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:
546 This returns the type of the application, currently the strings:
548 P15 = PKCS-15 structure used
550 OPENPGP = OpenPGP card
553 are implemented. These strings are aliases for the AID
555 S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
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:
561 S CERTINFO <certtype> <hexstring_with_id>
563 Where CERTTYPE is a number indicating the type of certificate:
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)
570 For certain cards, more information will be returned:
572 S KEY-FPR <no> <hexstring>
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.
578 S CA-FPR <no> <hexstring>
580 Similar to above, these are the fingerprints of keys assumed to be
583 S DISP-NAME <name_of_card_holder>
585 The name of the card holder as stored on the card; percent
586 escaping takes place, spaces are encoded as '+'
590 The URL to be used for locating the entire public key.
592 Note, that this function may be even be used on a locked card.
595 cmd_learn (assuan_context_t ctx, char *line)
597 ctrl_t ctrl = assuan_get_pointer (ctx);
600 if ((rc = open_card (ctrl, NULL)))
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 */
608 char *serial_and_stamp;
612 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
615 rc = estream_asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
618 return out_of_core ();
620 assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
622 if (!has_option (line, "--force"))
626 rc = estream_asprintf (&command, "KNOWNCARDP %s", serial_and_stamp);
629 xfree (serial_and_stamp);
630 return out_of_core ();
633 rc = assuan_inquire (ctx, command, NULL, NULL, 0);
637 if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
638 log_error ("inquire KNOWNCARDP failed: %s\n",
640 xfree (serial_and_stamp);
643 /* not canceled, so we have to proceeed */
645 xfree (serial_and_stamp);
648 /* Let the application print out its collection of useful status
651 rc = app_write_learn_status (ctrl->app_ctx, ctrl);
653 TEST_CARD_REMOVAL (ctrl, rc);
659 /* READCERT <hexified_certid>|<keyid>
661 Note, that this function may even be used on a locked card.
664 cmd_readcert (assuan_context_t ctx, char *line)
666 ctrl_t ctrl = assuan_get_pointer (ctx);
671 if ((rc = open_card (ctrl, NULL)))
674 line = xstrdup (line); /* Need a copy of the line. */
675 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
677 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
682 rc = assuan_send_data (ctx, cert, ncert);
688 TEST_CARD_REMOVAL (ctrl, rc);
695 Return the public key for the given cert or key ID as an standard
698 Note, that this function may even be used on a locked card.
701 cmd_readkey (assuan_context_t ctx, char *line)
703 ctrl_t ctrl = assuan_get_pointer (ctx);
705 unsigned char *cert = NULL;
707 ksba_cert_t kc = NULL;
712 if ((rc = open_card (ctrl, NULL)))
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
719 rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen);
721 { /* Yeah, got that key - send it back. */
722 rc = assuan_send_data (ctx, pk, pklen);
729 if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
730 log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
733 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
735 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
742 rc = ksba_cert_new (&kc);
748 rc = ksba_cert_init_from_mem (kc, cert, ncert);
751 log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
755 p = ksba_cert_get_public_key (kc);
758 rc = gpg_error (GPG_ERR_NO_PUBKEY);
762 n = gcry_sexp_canon_len (p, 0, NULL, NULL);
763 rc = assuan_send_data (ctx, p, n);
768 ksba_cert_release (kc);
770 TEST_CARD_REMOVAL (ctrl, rc);
777 /* SETDATA <hexstring>
779 The client should use this command to tell us the data he want to
782 cmd_setdata (assuan_context_t ctx, char *line)
784 ctrl_t ctrl = assuan_get_pointer (ctx);
789 if (locked_session && locked_session != ctrl->server_local)
790 return gpg_error (GPG_ERR_LOCKED);
792 /* Parse the hexstring. */
793 for (p=line,n=0; hexdigitp (p); p++, n++)
796 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
798 return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
800 return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
802 buf = xtrymalloc (n);
804 return out_of_core ();
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++)
816 pin_cb (void *opaque, const char *info, char **retstr)
818 assuan_context_t ctx = opaque;
821 unsigned char *value;
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. */
831 log_debug ("prompting for keypad entry '%s'\n", info);
832 rc = estream_asprintf (&command, "POPUPKEYPADPROMPT %s", info);
834 return gpg_error (gpg_err_code_from_errno (errno));
835 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
840 log_debug ("dismiss keypad entry prompt\n");
841 rc = assuan_inquire (ctx, "DISMISSKEYPADPROMPT",
842 &value, &valuelen, MAXLEN_PIN);
850 log_debug ("asking for PIN '%s'\n", info);
852 rc = estream_asprintf (&command, "NEEDPIN %s", info);
854 return gpg_error (gpg_err_code_from_errno (errno));
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);
863 if (!valuelen || value[valuelen-1])
865 /* We require that the returned value is an UTF-8 string */
867 return gpg_error (GPG_ERR_INV_RESPONSE);
869 *retstr = (char*)value;
874 /* PKSIGN [--hash=[rmd160|sha1|md5]] <hexified_id>
876 The --hash option is optional; the default is SHA1.
880 cmd_pksign (assuan_context_t ctx, char *line)
882 ctrl_t ctrl = assuan_get_pointer (ctx);
884 unsigned char *outdata;
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;
898 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
900 line = skip_options (line);
902 if ( IS_LOCKED (ctrl) )
903 return gpg_error (GPG_ERR_LOCKED);
905 if ((rc = open_card (ctrl, NULL)))
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);
913 return out_of_core ();
915 rc = app_sign (ctrl->app_ctx,
918 ctrl->in_data.value, ctrl->in_data.valuelen,
919 &outdata, &outdatalen);
924 log_error ("card_sign failed: %s\n", gpg_strerror (rc));
928 rc = assuan_send_data (ctx, outdata, outdatalen);
931 return rc; /* that is already an assuan error code */
934 TEST_CARD_REMOVAL (ctrl, rc);
938 /* PKAUTH <hexified_id>
942 cmd_pkauth (assuan_context_t ctx, char *line)
944 ctrl_t ctrl = assuan_get_pointer (ctx);
946 unsigned char *outdata;
950 if ( IS_LOCKED (ctrl) )
951 return gpg_error (GPG_ERR_LOCKED);
953 if ((rc = open_card (ctrl, NULL)))
957 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
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);
964 return out_of_core ();
966 rc = app_auth (ctrl->app_ctx,
969 ctrl->in_data.value, ctrl->in_data.valuelen,
970 &outdata, &outdatalen);
974 log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc));
978 rc = assuan_send_data (ctx, outdata, outdatalen);
981 return rc; /* that is already an assuan error code */
984 TEST_CARD_REMOVAL (ctrl, rc);
988 /* PKDECRYPT <hexified_id>
992 cmd_pkdecrypt (assuan_context_t ctx, char *line)
994 ctrl_t ctrl = assuan_get_pointer (ctx);
996 unsigned char *outdata;
1000 if ( IS_LOCKED (ctrl) )
1001 return gpg_error (GPG_ERR_LOCKED);
1003 if ((rc = open_card (ctrl, NULL)))
1006 keyidstr = xtrystrdup (line);
1008 return out_of_core ();
1009 rc = app_decipher (ctrl->app_ctx,
1012 ctrl->in_data.value, ctrl->in_data.valuelen,
1013 &outdata, &outdatalen);
1018 log_error ("card_create_signature failed: %s\n", gpg_strerror (rc));
1022 rc = assuan_send_data (ctx, outdata, outdatalen);
1025 return rc; /* that is already an assuan error code */
1028 TEST_CARD_REMOVAL (ctrl, rc);
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.
1040 However, the current implementation assumes that Name is not escaped;
1041 this works as long as noone uses arbitrary escaping.
1043 Note, that this function may even be used on a locked card.
1046 cmd_getattr (assuan_context_t ctx, char *line)
1048 ctrl_t ctrl = assuan_get_pointer (ctx);
1050 const char *keyword;
1052 if ((rc = open_card (ctrl, NULL)))
1056 for (; *line && !spacep (line); line++)
1061 /* (We ignore any garbage for now.) */
1063 /* FIXME: Applications should not return sensitive data if the card
1065 rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
1067 TEST_CARD_REMOVAL (ctrl, rc);
1072 /* SETATTR <name> <value>
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.
1078 However, the current implementation assumes that NAME is not
1079 escaped; this works as long as noone uses arbitrary escaping.
1081 A PIN will be requested for most NAMEs. See the corresponding
1082 setattr function of the actually used application (app-*.c) for
1085 cmd_setattr (assuan_context_t ctx, char *orig_line)
1087 ctrl_t ctrl = assuan_get_pointer (ctx);
1092 char *line, *linebuf;
1094 if ( IS_LOCKED (ctrl) )
1095 return gpg_error (GPG_ERR_LOCKED);
1097 if ((rc = open_card (ctrl, NULL)))
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);
1104 return out_of_core ();
1107 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1111 while (spacep (line))
1113 nbytes = percent_plus_unescape ((unsigned char*)line);
1115 rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx,
1116 (const unsigned char*)line, nbytes);
1119 TEST_CARD_REMOVAL (ctrl, rc);
1125 /* WRITECERT <hexified_certid>
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.
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
1136 cmd_writecert (assuan_context_t ctx, char *line)
1138 ctrl_t ctrl = assuan_get_pointer (ctx);
1141 unsigned char *certdata;
1144 if ( IS_LOCKED (ctrl) )
1145 return gpg_error (GPG_ERR_LOCKED);
1147 line = skip_options (line);
1150 return set_error (GPG_ERR_ASS_PARAMETER, "no certid given");
1152 while (*line && !spacep (line))
1156 if ((rc = open_card (ctrl, NULL)))
1160 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1162 certid = xtrystrdup (certid);
1164 return out_of_core ();
1166 /* Now get the actual keydata. */
1167 rc = assuan_inquire (ctx, "CERTDATA",
1168 &certdata, &certdatalen, MAXLEN_CERTDATA);
1175 /* Write the certificate to the card. */
1176 rc = app_writecert (ctrl->app_ctx, ctrl, certid,
1177 pin_cb, ctx, certdata, certdatalen);
1181 TEST_CARD_REMOVAL (ctrl, rc);
1187 /* WRITEKEY [--force] <keyid>
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
1197 A PIN will be requested for most NAMEs. See the corresponding
1198 writekey function of the actually used application (app-*.c) for
1201 cmd_writekey (assuan_context_t ctx, char *line)
1203 ctrl_t ctrl = assuan_get_pointer (ctx);
1206 int force = has_option (line, "--force");
1207 unsigned char *keydata;
1210 if ( IS_LOCKED (ctrl) )
1211 return gpg_error (GPG_ERR_LOCKED);
1213 line = skip_options (line);
1216 return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1218 while (*line && !spacep (line))
1222 if ((rc = open_card (ctrl, NULL)))
1226 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1228 keyid = xtrystrdup (keyid);
1230 return out_of_core ();
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);
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);
1248 TEST_CARD_REMOVAL (ctrl, rc);
1254 /* GENKEY [--force] [--timestamp=<isodate>] <no>
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:
1260 S KEY-FPR <hexstring>
1261 S KEY-CREATED-AT <seconds_since_epoch>
1262 S KEY-DATA [p|n] <hexdata>
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.
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.
1272 The public part of the key can also later be retrieved using the
1277 cmd_genkey (assuan_context_t ctx, char *line)
1279 ctrl_t ctrl = assuan_get_pointer (ctx);
1286 if ( IS_LOCKED (ctrl) )
1287 return gpg_error (GPG_ERR_LOCKED);
1289 force = has_option (line, "--force");
1291 if ((s=has_option_name (line, "--timestamp")))
1294 return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1295 timestamp = isotime2epoch (s+1);
1297 return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1303 line = skip_options (line);
1305 return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1307 while (*line && !spacep (line))
1311 if ((rc = open_card (ctrl, NULL)))
1315 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1317 keyno = xtrystrdup (keyno);
1319 return out_of_core ();
1320 rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
1321 timestamp, pin_cb, ctx);
1324 TEST_CARD_REMOVAL (ctrl, rc);
1331 Get NBYTES of random from the card and send them back as data.
1333 Note, that this function may be even be used on a locked card.
1336 cmd_random (assuan_context_t ctx, char *line)
1338 ctrl_t ctrl = assuan_get_pointer (ctx);
1341 unsigned char *buffer;
1344 return set_error (GPG_ERR_ASS_PARAMETER, "number of requested bytes missing");
1345 nbytes = strtoul (line, NULL, 0);
1347 if ((rc = open_card (ctrl, NULL)))
1351 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1353 buffer = xtrymalloc (nbytes);
1355 return out_of_core ();
1357 rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
1360 rc = assuan_send_data (ctx, buffer, nbytes);
1362 return rc; /* that is already an assuan error code */
1366 TEST_CARD_REMOVAL (ctrl, rc);
1371 /* PASSWD [--reset] [--nullpin] <chvno>
1373 Change the PIN or, if --reset is given, reset the retry counter of
1374 the card holder verfication vector CHVNO. The option --nullpin is
1375 used for TCOS cards to set the initial PIN. The format of CHVNO
1376 depends on the card application. */
1378 cmd_passwd (assuan_context_t ctx, char *line)
1380 ctrl_t ctrl = assuan_get_pointer (ctx);
1383 unsigned int flags = 0;
1385 if (has_option (line, "--reset"))
1386 flags |= APP_CHANGE_FLAG_RESET;
1387 if (has_option (line, "--nullpin"))
1388 flags |= APP_CHANGE_FLAG_NULLPIN;
1390 if ( IS_LOCKED (ctrl) )
1391 return gpg_error (GPG_ERR_LOCKED);
1393 line = skip_options (line);
1396 return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1398 while (*line && !spacep (line))
1402 if ((rc = open_card (ctrl, NULL)))
1406 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1408 chvnostr = xtrystrdup (chvnostr);
1410 return out_of_core ();
1411 rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
1413 log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1416 TEST_CARD_REMOVAL (ctrl, rc);
1423 Perform a VERIFY operation without doing anything else. This may
1424 be used to initialize a the PIN cache earlier to long lasting
1425 operations. Its use is highly application dependent.
1429 Perform a simple verify operation for CHV1 and CHV2, so that
1430 further operations won't ask for CHV2 and it is possible to do a
1431 cheap check on the PIN: If there is something wrong with the PIN
1432 entry system, only the regular CHV will get blocked and not the
1433 dangerous CHV3. IDSTR is the usual card's serial number in hex
1434 notation; an optional fingerprint part will get ignored. There
1435 is however a special mode if the IDSTR is sffixed with the
1436 literal string "[CHV3]": In this case the Admin PIN is checked
1437 if and only if the retry counter is still at 3.
1441 Any of the valid PIN Ids may be used. These are the strings:
1443 PW1.CH - Global password 1
1444 PW2.CH - Global password 2
1445 PW1.CH.SIG - SigG password 1
1446 PW2.CH.SIG - SigG password 2
1448 For a definitive list, see the implementation in app-nks.c.
1449 Note that we call a PW2.* PIN a "PUK" despite that since TCOS
1450 3.0 they are technically alternative PINs used to mutally
1455 cmd_checkpin (assuan_context_t ctx, char *line)
1457 ctrl_t ctrl = assuan_get_pointer (ctx);
1461 if ( IS_LOCKED (ctrl) )
1462 return gpg_error (GPG_ERR_LOCKED);
1464 if ((rc = open_card (ctrl, NULL)))
1468 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1470 /* We have to use a copy of the key ID because the function may use
1471 the pin_cb which in turn uses the assuan line buffer and thus
1472 overwriting the original line with the keyid. */
1473 idstr = xtrystrdup (line);
1475 return out_of_core ();
1477 rc = app_check_pin (ctrl->app_ctx, idstr, pin_cb, ctx);
1480 log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1482 TEST_CARD_REMOVAL (ctrl, rc);
1489 Grant exclusive card access to this session. Note that there is
1490 no lock counter used and a second lock from the same session will
1491 be ignored. A single unlock (or RESET) unlocks the session.
1492 Return GPG_ERR_LOCKED if another session has locked the reader.
1494 If the option --wait is given the command will wait until a
1495 lock has been released.
1498 cmd_lock (assuan_context_t ctx, char *line)
1500 ctrl_t ctrl = assuan_get_pointer (ctx);
1506 if (locked_session != ctrl->server_local)
1507 rc = gpg_error (GPG_ERR_LOCKED);
1510 locked_session = ctrl->server_local;
1513 if (rc && has_option (line, "--wait"))
1516 pth_sleep (1); /* Better implement an event mechanism. However,
1517 for card operations this should be
1519 /* FIXME: Need to check that the connection is still alive.
1520 This can be done by issuing status messages. */
1523 #endif /*USE_GNU_PTH*/
1526 log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1533 Release exclusive card access.
1536 cmd_unlock (assuan_context_t ctx, char *line)
1538 ctrl_t ctrl = assuan_get_pointer (ctx);
1545 if (locked_session != ctrl->server_local)
1546 rc = gpg_error (GPG_ERR_LOCKED);
1548 locked_session = NULL;
1551 rc = gpg_error (GPG_ERR_NOT_LOCKED);
1554 log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1561 Multi purpose command to return certain information.
1562 Supported values of WHAT are:
1564 version - Return the version of the program.
1565 pid - Return the process id of the server.
1567 socket_name - Return the name of the socket.
1569 status - Return the status of the current slot (in the future, may
1570 also return the status of all slots). The status is a list of
1571 one-character flags. The following flags are currently defined:
1572 'u' Usable card present. This is the normal state during operation.
1573 'r' Card removed. A reset is necessary.
1574 These flags are exclusive.
1576 reader_list - Return a list of detected card readers. Does
1577 currently only work with the internal CCID driver.
1579 deny_admin - Returns OK if admin commands are not allowed or
1580 GPG_ERR_GENERAL if admin commands are allowed.
1582 app_list - Return a list of supported applications. One
1583 application per line, fields delimited by colons,
1584 first field is the name.
1588 cmd_getinfo (assuan_context_t ctx, char *line)
1592 if (!strcmp (line, "version"))
1594 const char *s = VERSION;
1595 rc = assuan_send_data (ctx, s, strlen (s));
1597 else if (!strcmp (line, "pid"))
1601 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1602 rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1604 else if (!strcmp (line, "socket_name"))
1606 const char *s = scd_get_socket_name ();
1609 rc = assuan_send_data (ctx, s, strlen (s));
1611 rc = gpg_error (GPG_ERR_NO_DATA);
1613 else if (!strcmp (line, "status"))
1615 ctrl_t ctrl = assuan_get_pointer (ctx);
1616 int slot = ctrl->reader_slot;
1619 if (!ctrl->server_local->card_removed && slot != -1)
1621 struct slot_status_s *ss;
1623 if (!(slot >= 0 && slot < DIM(slot_table)))
1626 ss = &slot_table[slot];
1631 if (ss->any && (ss->status & 1))
1634 rc = assuan_send_data (ctx, &flag, 1);
1636 else if (!strcmp (line, "reader_list"))
1639 char *s = ccid_get_reader_list ();
1645 rc = assuan_send_data (ctx, s, strlen (s));
1647 rc = gpg_error (GPG_ERR_NO_DATA);
1650 else if (!strcmp (line, "deny_admin"))
1651 rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1652 else if (!strcmp (line, "app_list"))
1654 char *s = get_supported_applications ();
1656 rc = assuan_send_data (ctx, s, strlen (s));
1662 rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1669 Restart the current connection; this is a kind of warm reset. It
1670 deletes the context used by this connection but does not send a
1671 RESET to the card. Thus the card itself won't get reset.
1673 This is used by gpg-agent to reuse a primary pipe connection and
1674 may be used by clients to backup from a conflict in the serial
1675 command; i.e. to select another application.
1679 cmd_restart (assuan_context_t ctx, char *line)
1681 ctrl_t ctrl = assuan_get_pointer (ctx);
1687 release_application (ctrl->app_ctx);
1688 ctrl->app_ctx = NULL;
1690 if (locked_session && ctrl->server_local == locked_session)
1692 locked_session = NULL;
1693 log_info ("implicitly unlocking due to RESTART\n");
1701 Disconnect the card if it is not any longer used by other
1702 connections and the backend supports a disconnect operation.
1705 cmd_disconnect (assuan_context_t ctx, char *line)
1707 ctrl_t ctrl = assuan_get_pointer (ctx);
1711 ctrl->server_local->disconnect_allowed = 1;
1717 /* APDU [--atr] [--more] [hexstring]
1719 Send an APDU to the current reader. This command bypasses the high
1720 level functions and sends the data directly to the card. HEXSTRING
1721 is expected to be a proper APDU. If HEXSTRING is not given no
1722 commands are set to the card but the command will implictly check
1723 whether the card is ready for use.
1725 Using the option "--atr" returns the ATR of the card as a status
1726 message before any data like this:
1727 S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1
1729 Using the option --more handles the card status word MORE_DATA
1730 (61xx) and concatenate all reponses to one block.
1734 cmd_apdu (assuan_context_t ctx, char *line)
1736 ctrl_t ctrl = assuan_get_pointer (ctx);
1738 unsigned char *apdu;
1743 with_atr = has_option (line, "--atr");
1744 handle_more = has_option (line, "--more");
1746 line = skip_options (line);
1748 if ( IS_LOCKED (ctrl) )
1749 return gpg_error (GPG_ERR_LOCKED);
1751 if ((rc = open_card (ctrl, NULL)))
1760 atr = apdu_get_atr (ctrl->reader_slot, &atrlen);
1761 if (!atr || atrlen > sizeof hexbuf - 2 )
1763 rc = gpg_error (GPG_ERR_INV_CARD);
1766 bin2hex (atr, atrlen, hexbuf);
1768 send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1771 apdu = hex_to_buffer (line, &apdulen);
1774 rc = gpg_error_from_syserror ();
1779 unsigned char *result = NULL;
1782 rc = apdu_send_direct (ctrl->reader_slot, apdu, apdulen, handle_more,
1783 &result, &resultlen);
1785 log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1788 rc = assuan_send_data (ctx, result, resultlen);
1795 TEST_CARD_REMOVAL (ctrl, rc);
1800 /* KILLSCD - Commit suicide. */
1802 cmd_killscd (assuan_context_t ctx, char *line)
1804 ctrl_t ctrl = assuan_get_pointer (ctx);
1808 ctrl->server_local->stopme = 1;
1809 return gpg_error (GPG_ERR_EOF);
1814 /* Tell the assuan library about our commands */
1816 register_commands (assuan_context_t ctx)
1820 int (*handler)(assuan_context_t, char *line);
1822 { "SERIALNO", cmd_serialno },
1823 { "LEARN", cmd_learn },
1824 { "READCERT", cmd_readcert },
1825 { "READKEY", cmd_readkey },
1826 { "SETDATA", cmd_setdata },
1827 { "PKSIGN", cmd_pksign },
1828 { "PKAUTH", cmd_pkauth },
1829 { "PKDECRYPT", cmd_pkdecrypt },
1832 { "GETATTR", cmd_getattr },
1833 { "SETATTR", cmd_setattr },
1834 { "WRITECERT", cmd_writecert },
1835 { "WRITEKEY", cmd_writekey },
1836 { "GENKEY", cmd_genkey },
1837 { "RANDOM", cmd_random },
1838 { "PASSWD", cmd_passwd },
1839 { "CHECKPIN", cmd_checkpin },
1840 { "LOCK", cmd_lock },
1841 { "UNLOCK", cmd_unlock },
1842 { "GETINFO", cmd_getinfo },
1843 { "RESTART", cmd_restart },
1844 { "DISCONNECT", cmd_disconnect },
1845 { "APDU", cmd_apdu },
1846 { "KILLSCD", cmd_killscd },
1851 for (i=0; table[i].name; i++)
1853 rc = assuan_register_command (ctx, table[i].name, table[i].handler);
1857 assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1859 assuan_register_reset_notify (ctx, reset_notify);
1860 assuan_register_option_handler (ctx, option_handler);
1865 /* Startup the server. If FD is given as -1 this is simple pipe
1866 server, otherwise it is a regular server. Returns true if there
1867 are no more active asessions. */
1869 scd_command_handler (ctrl_t ctrl, int fd)
1872 assuan_context_t ctx;
1881 rc = assuan_init_pipe_server (&ctx, filedes);
1885 rc = assuan_init_socket_server_ext (&ctx, INT2FD(fd), 2);
1889 log_error ("failed to initialize the server: %s\n",
1893 rc = register_commands (ctx);
1896 log_error ("failed to register commands with Assuan: %s\n",
1900 assuan_set_pointer (ctx, ctrl);
1902 /* Allocate and initialize the server object. Put it into the list
1903 of active sessions. */
1904 ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
1905 ctrl->server_local->next_session = session_list;
1906 session_list = ctrl->server_local;
1907 ctrl->server_local->ctrl_backlink = ctrl;
1908 ctrl->server_local->assuan_ctx = ctx;
1911 assuan_set_log_stream (ctx, log_get_stream ());
1913 /* We open the reader right at startup so that the ticker is able to
1914 update the status file. */
1915 if (ctrl->reader_slot == -1)
1917 ctrl->reader_slot = get_reader_slot ();
1920 /* Command processing loop. */
1923 rc = assuan_accept (ctx);
1930 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1934 rc = assuan_process (ctx);
1937 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1942 /* Cleanup. We don't send an explicit reset to the card. */
1945 /* Release the server object. */
1946 if (session_list == ctrl->server_local)
1947 session_list = ctrl->server_local->next_session;
1950 struct server_local_s *sl;
1952 for (sl=session_list; sl->next_session; sl = sl->next_session)
1953 if (sl->next_session == ctrl->server_local)
1955 if (!sl->next_session)
1957 sl->next_session = ctrl->server_local->next_session;
1959 stopme = ctrl->server_local->stopme;
1960 xfree (ctrl->server_local);
1961 ctrl->server_local = NULL;
1963 /* Release the Assuan context. */
1964 assuan_deinit_server (ctx);
1969 /* If there are no more sessions return true. */
1970 return !session_list;
1974 /* Send a line with status information via assuan and escape all given
1975 buffers. The variable elements are pairs of (char *, size_t),
1976 terminated with a (NULL, 0). */
1978 send_status_info (ctrl_t ctrl, const char *keyword, ...)
1981 const unsigned char *value;
1985 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1987 va_start (arg_ptr, keyword);
1991 while ( (value = va_arg (arg_ptr, const unsigned char *)) )
1993 valuelen = va_arg (arg_ptr, size_t);
1995 continue; /* empty buffer */
2001 for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
2003 if (*value < ' ' || *value == '+')
2005 sprintf (p, "%%%02X", *value);
2008 else if (*value == ' ')
2015 assuan_write_status (ctx, keyword, buf);
2021 /* Send a ready formatted status line via assuan. */
2023 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
2025 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2027 if (strchr (args, '\n'))
2028 log_error ("error: LF detected in status line - not sending\n");
2030 assuan_write_status (ctx, keyword, args);
2034 /* Helper to send the clients a status change notification. */
2036 send_client_notifications (void)
2040 #ifdef HAVE_W32_SYSTEM
2048 struct server_local_s *sl;
2050 for (sl=session_list; sl; sl = sl->next_session)
2052 if (sl->event_signal && sl->assuan_ctx)
2054 pid_t pid = assuan_get_pid (sl->assuan_ctx);
2055 #ifdef HAVE_W32_SYSTEM
2056 HANDLE handle = (void *)sl->event_signal;
2058 for (kidx=0; kidx < killidx; kidx++)
2059 if (killed[kidx].pid == pid
2060 && killed[kidx].handle == handle)
2063 log_info ("event %lx (%p) already triggered for client %d\n",
2064 sl->event_signal, handle, (int)pid);
2067 log_info ("triggering event %lx (%p) for client %d\n",
2068 sl->event_signal, handle, (int)pid);
2069 if (!SetEvent (handle))
2070 log_error ("SetEvent(%lx) failed: %s\n",
2071 sl->event_signal, w32_strerror (-1));
2072 if (killidx < DIM (killed))
2074 killed[killidx].pid = pid;
2075 killed[killidx].handle = handle;
2079 #else /*!HAVE_W32_SYSTEM*/
2080 int signo = sl->event_signal;
2082 if (pid != (pid_t)(-1) && pid && signo > 0)
2084 for (kidx=0; kidx < killidx; kidx++)
2085 if (killed[kidx].pid == pid
2086 && killed[kidx].signo == signo)
2089 log_info ("signal %d already sent to client %d\n",
2093 log_info ("sending signal %d to client %d\n",
2096 if (killidx < DIM (killed))
2098 killed[killidx].pid = pid;
2099 killed[killidx].signo = signo;
2104 #endif /*!HAVE_W32_SYSTEM*/
2111 /* This is the core of scd_update_reader_status_file but the caller
2112 needs to take care of the locking. */
2114 update_reader_status_file (int set_card_removed_flag)
2117 unsigned int status, changed;
2119 /* Make sure that the reader has been opened. Like get_reader_slot,
2120 this part of the code assumes that there is only one reader. */
2121 if (!slot_table[0].valid)
2122 (void)get_reader_slot ();
2124 /* Note, that we only try to get the status, because it does not
2125 make sense to wait here for a operation to complete. If we are
2126 busy working with a card, delays in the status file update should
2128 for (idx=0; idx < DIM(slot_table); idx++)
2130 struct slot_status_s *ss = slot_table + idx;
2131 struct server_local_s *sl;
2134 if (!ss->valid || ss->slot == -1)
2135 continue; /* Not valid or reader not yet open. */
2137 sw_apdu = apdu_get_status (ss->slot, 0, &status, &changed);
2140 /* Get status failed. Ignore that. */
2144 if (!ss->any || ss->status != status || ss->changed != changed )
2150 log_info ("updating slot %d status: 0x%04X->0x%04X (%u->%u)\n",
2151 ss->slot, ss->status, status, ss->changed, changed);
2152 ss->status = status;
2153 ss->changed = changed;
2155 /* FIXME: Should this be IDX instead of ss->slot? This
2156 depends on how client sessions will associate the reader
2157 status with their session. */
2158 snprintf (templ, sizeof templ, "reader_%d.status", ss->slot);
2159 fname = make_filename (opt.homedir, templ, NULL );
2160 fp = fopen (fname, "w");
2163 fprintf (fp, "%s\n",
2164 (status & 1)? "USABLE":
2165 (status & 4)? "ACTIVE":
2166 (status & 2)? "PRESENT": "NOCARD");
2171 /* If a status script is executable, run it. */
2173 const char *args[9], *envs[2];
2174 char numbuf1[30], numbuf2[30], numbuf3[30];
2175 char *homestr, *envstr;
2178 homestr = make_filename (opt.homedir, NULL);
2179 if (estream_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
2180 log_error ("out of core while building environment\n");
2186 sprintf (numbuf1, "%d", ss->slot);
2187 sprintf (numbuf2, "0x%04X", ss->status);
2188 sprintf (numbuf3, "0x%04X", status);
2189 args[0] = "--reader-port";
2191 args[2] = "--old-code";
2193 args[4] = "--new-code";
2195 args[6] = "--status";
2196 args[7] = ((status & 1)? "USABLE":
2197 (status & 4)? "ACTIVE":
2198 (status & 2)? "PRESENT": "NOCARD");
2201 fname = make_filename (opt.homedir, "scd-event", NULL);
2202 err = gnupg_spawn_process_detached (fname, args, envs);
2203 if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
2204 log_error ("failed to run event handler `%s': %s\n",
2205 fname, gpg_strerror (err));
2212 /* Set the card removed flag for all current sessions. We
2213 will set this on any card change because a reset or
2214 SERIALNO request must be done in any case. */
2215 if (ss->any && set_card_removed_flag)
2216 update_card_removed (idx, 1);
2220 /* Send a signal to all clients who applied for it. */
2221 send_client_notifications ();
2224 /* Check whether a disconnect is pending. */
2225 if (opt.card_timeout)
2227 for (sl=session_list; sl; sl = sl->next_session)
2228 if (!sl->disconnect_allowed)
2230 if (session_list && !sl)
2232 /* FIXME: Use a real timeout. */
2233 /* At least one connection and all allow a disconnect. */
2234 log_info ("disconnecting card in slot %d\n", ss->slot);
2235 apdu_disconnect (ss->slot);
2242 /* This function is called by the ticker thread to check for changes
2243 of the reader stati. It updates the reader status files and if
2244 requested by the caller also send a signal to the caller. */
2246 scd_update_reader_status_file (void)
2248 if (!pth_mutex_acquire (&status_file_update_lock, 1, NULL))
2249 return; /* locked - give up. */
2250 update_reader_status_file (1);
2251 if (!pth_mutex_release (&status_file_update_lock))
2252 log_error ("failed to release status_file_update lock\n");