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
;
120 /* The table with information on all used slots. FIXME: This is a
121 different slot number than the one used by the APDU layer, and
122 should be renamed. */
123 static struct slot_status_s slot_table
[10];
126 /* To keep track of all running sessions, we link all active server
127 contexts and the anchor in this variable. */
128 static struct server_local_s
*session_list
;
130 /* If a session has been locked we store a link to its server object
132 static struct server_local_s
*locked_session
;
134 /* While doing a reset we need to make sure that the ticker does not
135 call scd_update_reader_status_file while we are using it. */
136 static pth_mutex_t status_file_update_lock
;
139 /*-- Local prototypes --*/
140 static void update_reader_status_file (int set_card_removed_flag
);
145 /* This function must be called once to initialize this module. This
146 has to be done before a second thread is spawned. We can't do the
147 static initialization because Pth emulation code might not be able
148 to do a static init; in particular, it is not possible for W32. */
150 initialize_module_command (void)
152 static int initialized
;
156 if (pth_mutex_init (&status_file_update_lock
))
162 /* Update the CARD_REMOVED element of all sessions using the reader
163 given by SLOT to VALUE */
165 update_card_removed (int slot
, int value
)
167 struct server_local_s
*sl
;
169 for (sl
=session_list
; sl
; sl
= sl
->next_session
)
170 if (sl
->ctrl_backlink
171 && sl
->ctrl_backlink
->reader_slot
== slot
)
173 sl
->card_removed
= value
;
175 /* Let the card application layer know about the removal. */
177 application_notify_card_reset (slot
);
182 /* Check whether the option NAME appears in LINE */
184 has_option (const char *line
, const char *name
)
187 int n
= strlen (name
);
189 s
= strstr (line
, name
);
190 return (s
&& (s
== line
|| spacep (s
-1)) && (!s
[n
] || spacep (s
+n
)));
193 /* Same as has_option but does only test for the name of the option
194 and ignores an argument, i.e. with NAME being "--hash" it would
195 return a pointer for "--hash" as well as for "--hash=foo". If
196 thhere is no such option NULL is returned. The pointer returned
197 points right behind the option name, this may be an equal sign, Nul
200 has_option_name (const char *line
, const char *name
)
203 int n
= strlen (name
);
205 s
= strstr (line
, name
);
206 return (s
&& (s
== line
|| spacep (s
-1))
207 && (!s
[n
] || spacep (s
+n
) || s
[n
] == '=')) ? (s
+n
) : NULL
;
211 /* Skip over options. It is assumed that leading spaces have been
212 removed (this is the case for lines passed to a handler from
213 assuan). Blanks after the options are also removed. */
215 skip_options (char *line
)
217 while ( *line
== '-' && line
[1] == '-' )
219 while (*line
&& !spacep (line
))
221 while (spacep (line
))
229 /* Convert the STRING into a newly allocated buffer while translating
230 the hex numbers. Stops at the first invalid character. Blanks and
231 colons are allowed to separate the hex digits. Returns NULL on
232 error or a newly malloced buffer and its length in LENGTH. */
233 static unsigned char *
234 hex_to_buffer (const char *string
, size_t *r_length
)
236 unsigned char *buffer
;
240 buffer
= xtrymalloc (strlen (string
)+1);
243 for (s
=string
, n
=0; *s
; s
++)
245 if (spacep (s
) || *s
== ':')
247 if (hexdigitp (s
) && hexdigitp (s
+1))
249 buffer
[n
++] = xtoi_2 (s
);
261 /* Reset the card and free the application context. With SEND_RESET
262 set to true actually send a RESET to the reader; this is the normal
263 way of calling the function. */
265 do_reset (ctrl_t ctrl
, int send_reset
)
267 int slot
= ctrl
->reader_slot
;
269 if (!(slot
== -1 || (slot
>= 0 && slot
< DIM(slot_table
))))
272 /* If there is an active application, release it. */
275 release_application (ctrl
->app_ctx
);
276 ctrl
->app_ctx
= NULL
;
279 /* If we want a real reset for the card, send the reset APDU and
280 tell the application layer about it. */
281 if (slot
!= -1 && send_reset
&& !IS_LOCKED (ctrl
) )
283 if (apdu_reset (slot
))
285 slot_table
[slot
].reset_failed
= 1;
287 application_notify_card_reset (slot
);
290 /* If we hold a lock, unlock now. */
291 if (locked_session
&& ctrl
->server_local
== locked_session
)
293 locked_session
= NULL
;
294 log_info ("implicitly unlocking due to RESET\n");
297 /* Reset the card removed flag for the current reader. We need to
298 take the lock here so that the ticker thread won't concurrently
299 try to update the file. Calling update_reader_status_file is
300 required to get hold of the new status of the card in the slot
302 if (!pth_mutex_acquire (&status_file_update_lock
, 0, NULL
))
304 log_error ("failed to acquire status_fle_update lock\n");
305 ctrl
->reader_slot
= -1;
308 update_reader_status_file (0); /* Update slot status table. */
309 update_card_removed (slot
, 0); /* Clear card_removed flag. */
310 if (!pth_mutex_release (&status_file_update_lock
))
311 log_error ("failed to release status_file_update lock\n");
313 /* Do this last, so that the update_card_removed above does its job. */
314 ctrl
->reader_slot
= -1;
319 reset_notify (assuan_context_t ctx
)
321 ctrl_t ctrl
= assuan_get_pointer (ctx
);
328 option_handler (assuan_context_t ctx
, const char *key
, const char *value
)
330 ctrl_t ctrl
= assuan_get_pointer (ctx
);
332 if (!strcmp (key
, "event-signal"))
334 /* A value of 0 is allowed to reset the event signal. */
335 #ifdef HAVE_W32_SYSTEM
337 return gpg_error (GPG_ERR_ASS_PARAMETER
);
338 ctrl
->server_local
->event_signal
= strtoul (value
, NULL
, 16);
340 int i
= *value
? atoi (value
) : -1;
342 return gpg_error (GPG_ERR_ASS_PARAMETER
);
343 ctrl
->server_local
->event_signal
= i
;
351 /* Return the slot of the current reader or open the reader if no
352 other sessions are using a reader. Note, that we currently support
353 only one reader but most of the code (except for this function)
354 should be able to cope with several readers. */
356 get_reader_slot (void)
358 struct slot_status_s
*ss
;
360 ss
= &slot_table
[0]; /* One reader for now. */
362 /* Initialize the item if needed. */
369 /* Try to open the reader. */
371 ss
->slot
= apdu_open_reader (opt
.reader_port
);
373 /* Return the slot_table index. */
377 /* If the card has not yet been opened, do it. Note that this
378 function returns an Assuan error, so don't map the error a second
380 static assuan_error_t
381 open_card (ctrl_t ctrl
, const char *apptype
)
386 /* If we ever got a card not present error code, return that. Only
387 the SERIALNO command and a reset are able to clear from that
389 if (ctrl
->server_local
->card_removed
)
390 return gpg_error (GPG_ERR_CARD_REMOVED
);
392 if ( IS_LOCKED (ctrl
) )
393 return gpg_error (GPG_ERR_LOCKED
);
397 /* Already initialized for one specific application. Need to
398 check that the client didn't requested a specific application
399 different from the one in use. */
400 return check_application_conflict (ctrl
, apptype
);
403 if (ctrl
->reader_slot
!= -1)
404 slot
= ctrl
->reader_slot
;
406 slot
= get_reader_slot ();
407 ctrl
->reader_slot
= slot
;
409 err
= gpg_error (GPG_ERR_CARD
);
412 /* Fixme: We should move the apdu_connect call to
413 select_application. */
416 ctrl
->server_local
->disconnect_allowed
= 0;
417 sw
= apdu_connect (slot
);
418 if (sw
&& sw
!= SW_HOST_ALREADY_CONNECTED
)
420 if (sw
== SW_HOST_NO_CARD
)
421 err
= gpg_error (GPG_ERR_CARD_NOT_PRESENT
);
423 err
= gpg_error (GPG_ERR_CARD
);
426 err
= select_application (ctrl
, slot
, apptype
, &ctrl
->app_ctx
);
429 TEST_CARD_REMOVAL (ctrl
, err
);
434 /* Do the percent and plus/space unescaping in place and return the
435 length of the valid buffer. */
437 percent_plus_unescape (unsigned char *string
)
439 unsigned char *p
= string
;
444 if (*string
== '%' && string
[1] && string
[2])
447 *p
++ = xtoi_2 (string
);
451 else if (*string
== '+')
469 /* SERIALNO [APPTYPE]
471 Return the serial number of the card using a status reponse. This
472 functon should be used to check for the presence of a card.
474 If APPTYPE is given, an application of that type is selected and an
475 error is returned if the application is not supported or available.
476 The default is to auto-select the application using a hardwired
477 preference system. Note, that a future extension to this function
478 may allow to specify a list and order of applications to try.
480 This function is special in that it can be used to reset the card.
481 Most other functions will return an error when a card change has
482 been detected and the use of this function is therefore required.
484 Background: We want to keep the client clear of handling card
485 changes between operations; i.e. the client can assume that all
486 operations are done on the same card unless he calls this function.
489 cmd_serialno (assuan_context_t ctx
, char *line
)
491 ctrl_t ctrl
= assuan_get_pointer (ctx
);
493 char *serial_and_stamp
;
497 /* Clear the remove flag so that the open_card is able to reread it. */
498 if (ctrl
->server_local
->card_removed
)
500 if ( IS_LOCKED (ctrl
) )
501 return gpg_error (GPG_ERR_LOCKED
);
505 if ((rc
= open_card (ctrl
, *line
? line
:NULL
)))
508 rc
= app_get_serial_and_stamp (ctrl
->app_ctx
, &serial
, &stamp
);
512 rc
= estream_asprintf (&serial_and_stamp
, "%s %lu",
513 serial
, (unsigned long)stamp
);
516 return out_of_core ();
518 assuan_write_status (ctx
, "SERIALNO", serial_and_stamp
);
519 xfree (serial_and_stamp
);
528 Learn all useful information of the currently inserted card. When
529 used without the force options, the command might do an INQUIRE
532 INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>
534 The client should just send an "END" if the processing should go on
535 or a "CANCEL" to force the function to terminate with a Cancel
536 error message. The response of this command is a list of status
537 lines formatted as this:
541 This returns the type of the application, currently the strings:
543 P15 = PKCS-15 structure used
545 OPENPGP = OpenPGP card
547 are implemented. These strings are aliases for the AID
549 S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
551 If there is no certificate yet stored on the card a single "X" is
552 returned as the keygrip. In addition to the keypair info, information
553 about all certificates stored on the card is also returned:
555 S CERTINFO <certtype> <hexstring_with_id>
557 Where CERTTYPE is a number indicating the type of certificate:
559 100 := Regular X.509 cert
560 101 := Trusted X.509 cert
561 102 := Useful X.509 cert
562 110 := Root CA cert (DINSIG)
564 For certain cards, more information will be returned:
566 S KEY-FPR <no> <hexstring>
568 For OpenPGP cards this returns the stored fingerprints of the
569 keys. This can be used check whether a key is available on the
570 card. NO may be 1, 2 or 3.
572 S CA-FPR <no> <hexstring>
574 Similar to above, these are the fingerprints of keys assumed to be
577 S DISP-NAME <name_of_card_holder>
579 The name of the card holder as stored on the card; percent
580 escaping takes place, spaces are encoded as '+'
584 The URL to be used for locating the entire public key.
586 Note, that this function may be even be used on a locked card.
589 cmd_learn (assuan_context_t ctx
, char *line
)
591 ctrl_t ctrl
= assuan_get_pointer (ctx
);
594 if ((rc
= open_card (ctrl
, NULL
)))
597 /* Unless the force option is used we try a shortcut by identifying
598 the card using a serial number and inquiring the client with
599 that. The client may choose to cancel the operation if he already
600 knows about this card */
602 char *serial_and_stamp
;
606 rc
= app_get_serial_and_stamp (ctrl
->app_ctx
, &serial
, &stamp
);
609 rc
= estream_asprintf (&serial_and_stamp
, "%s %lu", serial
, (unsigned long)stamp
);
612 return out_of_core ();
614 assuan_write_status (ctx
, "SERIALNO", serial_and_stamp
);
616 if (!has_option (line
, "--force"))
620 rc
= estream_asprintf (&command
, "KNOWNCARDP %s", serial_and_stamp
);
623 xfree (serial_and_stamp
);
624 return out_of_core ();
627 rc
= assuan_inquire (ctx
, command
, NULL
, NULL
, 0);
631 if (gpg_err_code (rc
) != GPG_ERR_ASS_CANCELED
)
632 log_error ("inquire KNOWNCARDP failed: %s\n",
634 xfree (serial_and_stamp
);
637 /* not canceled, so we have to proceeed */
639 xfree (serial_and_stamp
);
642 /* Let the application print out its collection of useful status
645 rc
= app_write_learn_status (ctrl
->app_ctx
, ctrl
);
647 TEST_CARD_REMOVAL (ctrl
, rc
);
653 /* READCERT <hexified_certid>|<keyid>
655 Note, that this function may even be used on a locked card.
658 cmd_readcert (assuan_context_t ctx
, char *line
)
660 ctrl_t ctrl
= assuan_get_pointer (ctx
);
665 if ((rc
= open_card (ctrl
, NULL
)))
668 line
= xstrdup (line
); /* Need a copy of the line. */
669 rc
= app_readcert (ctrl
->app_ctx
, line
, &cert
, &ncert
);
671 log_error ("app_readcert failed: %s\n", gpg_strerror (rc
));
676 rc
= assuan_send_data (ctx
, cert
, ncert
);
682 TEST_CARD_REMOVAL (ctrl
, rc
);
689 Return the public key for the given cert or key ID as an standard
692 Note, that this function may even be used on a locked card.
695 cmd_readkey (assuan_context_t ctx
, char *line
)
697 ctrl_t ctrl
= assuan_get_pointer (ctx
);
699 unsigned char *cert
= NULL
;
701 ksba_cert_t kc
= NULL
;
706 if ((rc
= open_card (ctrl
, NULL
)))
709 line
= xstrdup (line
); /* Need a copy of the line. */
710 /* If the application supports the READKEY function we use that.
711 Otherwise we use the old way by extracting it from the
713 rc
= app_readkey (ctrl
->app_ctx
, line
, &pk
, &pklen
);
715 { /* Yeah, got that key - send it back. */
716 rc
= assuan_send_data (ctx
, pk
, pklen
);
723 if (gpg_err_code (rc
) != GPG_ERR_UNSUPPORTED_OPERATION
)
724 log_error ("app_readkey failed: %s\n", gpg_strerror (rc
));
727 rc
= app_readcert (ctrl
->app_ctx
, line
, &cert
, &ncert
);
729 log_error ("app_readcert failed: %s\n", gpg_strerror (rc
));
736 rc
= ksba_cert_new (&kc
);
742 rc
= ksba_cert_init_from_mem (kc
, cert
, ncert
);
745 log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc
));
749 p
= ksba_cert_get_public_key (kc
);
752 rc
= gpg_error (GPG_ERR_NO_PUBKEY
);
756 n
= gcry_sexp_canon_len (p
, 0, NULL
, NULL
);
757 rc
= assuan_send_data (ctx
, p
, n
);
762 ksba_cert_release (kc
);
764 TEST_CARD_REMOVAL (ctrl
, rc
);
771 /* SETDATA <hexstring>
773 The client should use this command to tell us the data he want to
776 cmd_setdata (assuan_context_t ctx
, char *line
)
778 ctrl_t ctrl
= assuan_get_pointer (ctx
);
783 if (locked_session
&& locked_session
!= ctrl
->server_local
)
784 return gpg_error (GPG_ERR_LOCKED
);
786 /* Parse the hexstring. */
787 for (p
=line
,n
=0; hexdigitp (p
); p
++, n
++)
790 return set_error (GPG_ERR_ASS_PARAMETER
, "invalid hexstring");
792 return set_error (GPG_ERR_ASS_PARAMETER
, "no data given");
794 return set_error (GPG_ERR_ASS_PARAMETER
, "odd number of digits");
796 buf
= xtrymalloc (n
);
798 return out_of_core ();
800 ctrl
->in_data
.value
= buf
;
801 ctrl
->in_data
.valuelen
= n
;
802 for (p
=line
, n
=0; n
< ctrl
->in_data
.valuelen
; p
+= 2, n
++)
810 pin_cb (void *opaque
, const char *info
, char **retstr
)
812 assuan_context_t ctx
= opaque
;
815 unsigned char *value
;
820 /* We prompt for keypad entry. To make sure that the popup has
821 been show we use an inquire and not just a status message.
822 We ignore any value returned. */
825 log_debug ("prompting for keypad entry '%s'\n", info
);
826 rc
= estream_asprintf (&command
, "POPUPKEYPADPROMPT %s", info
);
828 return gpg_error (gpg_err_code_from_errno (errno
));
829 rc
= assuan_inquire (ctx
, command
, &value
, &valuelen
, MAXLEN_PIN
);
834 log_debug ("dismiss keypad entry prompt\n");
835 rc
= assuan_inquire (ctx
, "DISMISSKEYPADPROMPT",
836 &value
, &valuelen
, MAXLEN_PIN
);
844 log_debug ("asking for PIN '%s'\n", info
);
846 rc
= estream_asprintf (&command
, "NEEDPIN %s", info
);
848 return gpg_error (gpg_err_code_from_errno (errno
));
850 /* Fixme: Write an inquire function which returns the result in
851 secure memory and check all further handling of the PIN. */
852 rc
= assuan_inquire (ctx
, command
, &value
, &valuelen
, MAXLEN_PIN
);
857 if (!valuelen
|| value
[valuelen
-1])
859 /* We require that the returned value is an UTF-8 string */
861 return gpg_error (GPG_ERR_INV_RESPONSE
);
863 *retstr
= (char*)value
;
868 /* PKSIGN [--hash=[rmd160|sha1|md5]] <hexified_id>
870 The --hash option is optional; the default is SHA1.
874 cmd_pksign (assuan_context_t ctx
, char *line
)
876 ctrl_t ctrl
= assuan_get_pointer (ctx
);
878 unsigned char *outdata
;
883 if (has_option (line
, "--hash=rmd160"))
884 hash_algo
= GCRY_MD_RMD160
;
885 else if (has_option (line
, "--hash=sha1"))
886 hash_algo
= GCRY_MD_SHA1
;
887 else if (has_option (line
, "--hash=md5"))
888 hash_algo
= GCRY_MD_MD5
;
889 else if (!strstr (line
, "--"))
890 hash_algo
= GCRY_MD_SHA1
;
892 return set_error (GPG_ERR_ASS_PARAMETER
, "invalid hash algorithm");
894 line
= skip_options (line
);
896 if ( IS_LOCKED (ctrl
) )
897 return gpg_error (GPG_ERR_LOCKED
);
899 if ((rc
= open_card (ctrl
, NULL
)))
902 /* We have to use a copy of the key ID because the function may use
903 the pin_cb which in turn uses the assuan line buffer and thus
904 overwriting the original line with the keyid */
905 keyidstr
= xtrystrdup (line
);
907 return out_of_core ();
909 rc
= app_sign (ctrl
->app_ctx
,
912 ctrl
->in_data
.value
, ctrl
->in_data
.valuelen
,
913 &outdata
, &outdatalen
);
918 log_error ("card_sign failed: %s\n", gpg_strerror (rc
));
922 rc
= assuan_send_data (ctx
, outdata
, outdatalen
);
925 return rc
; /* that is already an assuan error code */
928 TEST_CARD_REMOVAL (ctrl
, rc
);
932 /* PKAUTH <hexified_id>
936 cmd_pkauth (assuan_context_t ctx
, char *line
)
938 ctrl_t ctrl
= assuan_get_pointer (ctx
);
940 unsigned char *outdata
;
944 if ( IS_LOCKED (ctrl
) )
945 return gpg_error (GPG_ERR_LOCKED
);
947 if ((rc
= open_card (ctrl
, NULL
)))
951 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
953 /* We have to use a copy of the key ID because the function may use
954 the pin_cb which in turn uses the assuan line buffer and thus
955 overwriting the original line with the keyid */
956 keyidstr
= xtrystrdup (line
);
958 return out_of_core ();
960 rc
= app_auth (ctrl
->app_ctx
,
963 ctrl
->in_data
.value
, ctrl
->in_data
.valuelen
,
964 &outdata
, &outdatalen
);
968 log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc
));
972 rc
= assuan_send_data (ctx
, outdata
, outdatalen
);
975 return rc
; /* that is already an assuan error code */
978 TEST_CARD_REMOVAL (ctrl
, rc
);
982 /* PKDECRYPT <hexified_id>
986 cmd_pkdecrypt (assuan_context_t ctx
, char *line
)
988 ctrl_t ctrl
= assuan_get_pointer (ctx
);
990 unsigned char *outdata
;
994 if ( IS_LOCKED (ctrl
) )
995 return gpg_error (GPG_ERR_LOCKED
);
997 if ((rc
= open_card (ctrl
, NULL
)))
1000 keyidstr
= xtrystrdup (line
);
1002 return out_of_core ();
1003 rc
= app_decipher (ctrl
->app_ctx
,
1006 ctrl
->in_data
.value
, ctrl
->in_data
.valuelen
,
1007 &outdata
, &outdatalen
);
1012 log_error ("card_create_signature failed: %s\n", gpg_strerror (rc
));
1016 rc
= assuan_send_data (ctx
, outdata
, outdatalen
);
1019 return rc
; /* that is already an assuan error code */
1022 TEST_CARD_REMOVAL (ctrl
, rc
);
1029 This command is used to retrieve data from a smartcard. The
1030 allowed names depend on the currently selected smartcard
1031 application. NAME must be percent and '+' escaped. The value is
1032 returned through status message, see the LEARN command for details.
1034 However, the current implementation assumes that Name is not escaped;
1035 this works as long as noone uses arbitrary escaping.
1037 Note, that this function may even be used on a locked card.
1040 cmd_getattr (assuan_context_t ctx
, char *line
)
1042 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1044 const char *keyword
;
1046 if ((rc
= open_card (ctrl
, NULL
)))
1050 for (; *line
&& !spacep (line
); line
++)
1055 /* (We ignore any garbage for now.) */
1057 /* FIXME: Applications should not return sensitive data if the card
1059 rc
= app_getattr (ctrl
->app_ctx
, ctrl
, keyword
);
1061 TEST_CARD_REMOVAL (ctrl
, rc
);
1066 /* SETATTR <name> <value>
1068 This command is used to store data on a a smartcard. The allowed
1069 names and values are depend on the currently selected smartcard
1070 application. NAME and VALUE must be percent and '+' escaped.
1072 However, the current implementation assumes that NAME is not
1073 escaped; this works as long as noone uses arbitrary escaping.
1075 A PIN will be requested for most NAMEs. See the corresponding
1076 setattr function of the actually used application (app-*.c) for
1079 cmd_setattr (assuan_context_t ctx
, char *orig_line
)
1081 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1086 char *line
, *linebuf
;
1088 if ( IS_LOCKED (ctrl
) )
1089 return gpg_error (GPG_ERR_LOCKED
);
1091 if ((rc
= open_card (ctrl
, NULL
)))
1094 /* We need to use a copy of LINE, because PIN_CB uses the same
1095 context and thus reuses the Assuan provided LINE. */
1096 line
= linebuf
= xtrystrdup (orig_line
);
1098 return out_of_core ();
1101 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
1105 while (spacep (line
))
1107 nbytes
= percent_plus_unescape ((unsigned char*)line
);
1109 rc
= app_setattr (ctrl
->app_ctx
, keyword
, pin_cb
, ctx
,
1110 (const unsigned char*)line
, nbytes
);
1113 TEST_CARD_REMOVAL (ctrl
, rc
);
1119 /* WRITECERT <hexified_certid>
1121 This command is used to store a certifciate on a smartcard. The
1122 allowed certids depend on the currently selected smartcard
1123 application. The actual certifciate is requested using the inquiry
1124 "CERTDATA" and needs to be provided in its raw (e.g. DER) form.
1126 In almost all cases a a PIN will be requested. See the related
1127 writecert function of the actually used application (app-*.c) for
1130 cmd_writecert (assuan_context_t ctx
, char *line
)
1132 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1135 unsigned char *certdata
;
1138 if ( IS_LOCKED (ctrl
) )
1139 return gpg_error (GPG_ERR_LOCKED
);
1141 line
= skip_options (line
);
1144 return set_error (GPG_ERR_ASS_PARAMETER
, "no certid given");
1146 while (*line
&& !spacep (line
))
1150 if ((rc
= open_card (ctrl
, NULL
)))
1154 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1156 certid
= xtrystrdup (certid
);
1158 return out_of_core ();
1160 /* Now get the actual keydata. */
1161 rc
= assuan_inquire (ctx
, "CERTDATA",
1162 &certdata
, &certdatalen
, MAXLEN_CERTDATA
);
1169 /* Write the certificate to the card. */
1170 rc
= app_writecert (ctrl
->app_ctx
, ctrl
, certid
,
1171 pin_cb
, ctx
, certdata
, certdatalen
);
1175 TEST_CARD_REMOVAL (ctrl
, rc
);
1181 /* WRITEKEY [--force] <keyid>
1183 This command is used to store a secret key on a a smartcard. The
1184 allowed keyids depend on the currently selected smartcard
1185 application. The actual keydata is requested using the inquiry
1186 "KEYDATA" and need to be provided without any protection. With
1187 --force set an existing key under this KEYID will get overwritten.
1188 The keydata is expected to be the usual canonical encoded
1191 A PIN will be requested for most NAMEs. See the corresponding
1192 writekey function of the actually used application (app-*.c) for
1195 cmd_writekey (assuan_context_t ctx
, char *line
)
1197 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1200 int force
= has_option (line
, "--force");
1201 unsigned char *keydata
;
1204 if ( IS_LOCKED (ctrl
) )
1205 return gpg_error (GPG_ERR_LOCKED
);
1207 line
= skip_options (line
);
1210 return set_error (GPG_ERR_ASS_PARAMETER
, "no keyid given");
1212 while (*line
&& !spacep (line
))
1216 if ((rc
= open_card (ctrl
, NULL
)))
1220 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1222 keyid
= xtrystrdup (keyid
);
1224 return out_of_core ();
1226 /* Now get the actual keydata. */
1227 assuan_begin_confidential (ctx
);
1228 rc
= assuan_inquire (ctx
, "KEYDATA", &keydata
, &keydatalen
, MAXLEN_KEYDATA
);
1229 assuan_end_confidential (ctx
);
1236 /* Write the key to the card. */
1237 rc
= app_writekey (ctrl
->app_ctx
, ctrl
, keyid
, force
? 1:0,
1238 pin_cb
, ctx
, keydata
, keydatalen
);
1242 TEST_CARD_REMOVAL (ctrl
, rc
);
1248 /* GENKEY [--force] [--timestamp=<isodate>] <no>
1250 Generate a key on-card identified by NO, which is application
1251 specific. Return values are application specific. For OpenPGP
1252 cards 2 status lines are returned:
1254 S KEY-FPR <hexstring>
1255 S KEY-CREATED-AT <seconds_since_epoch>
1256 S KEY-DATA [p|n] <hexdata>
1258 --force is required to overwrite an already existing key. The
1259 KEY-CREATED-AT is required for further processing because it is
1260 part of the hashed key material for the fingerprint.
1262 If --timestamp is given an OpenPGP key will be created using this
1263 value. The value needs to be in ISO Format; e.g.
1264 "--timestamp=20030316T120000" and after 1970-01-01 00:00:00.
1266 The public part of the key can also later be retrieved using the
1271 cmd_genkey (assuan_context_t ctx
, char *line
)
1273 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1280 if ( IS_LOCKED (ctrl
) )
1281 return gpg_error (GPG_ERR_LOCKED
);
1283 force
= has_option (line
, "--force");
1285 if ((s
=has_option_name (line
, "--timestamp")))
1288 return set_error (GPG_ERR_ASS_PARAMETER
, "missing value for option");
1289 timestamp
= isotime2epoch (s
+1);
1291 return set_error (GPG_ERR_ASS_PARAMETER
, "invalid time value");
1297 line
= skip_options (line
);
1299 return set_error (GPG_ERR_ASS_PARAMETER
, "no key number given");
1301 while (*line
&& !spacep (line
))
1305 if ((rc
= open_card (ctrl
, NULL
)))
1309 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1311 keyno
= xtrystrdup (keyno
);
1313 return out_of_core ();
1314 rc
= app_genkey (ctrl
->app_ctx
, ctrl
, keyno
, force
? 1:0,
1315 timestamp
, pin_cb
, ctx
);
1318 TEST_CARD_REMOVAL (ctrl
, rc
);
1325 Get NBYTES of random from the card and send them back as data.
1327 Note, that this function may be even be used on a locked card.
1330 cmd_random (assuan_context_t ctx
, char *line
)
1332 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1335 unsigned char *buffer
;
1338 return set_error (GPG_ERR_ASS_PARAMETER
, "number of requested bytes missing");
1339 nbytes
= strtoul (line
, NULL
, 0);
1341 if ((rc
= open_card (ctrl
, NULL
)))
1345 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1347 buffer
= xtrymalloc (nbytes
);
1349 return out_of_core ();
1351 rc
= app_get_challenge (ctrl
->app_ctx
, nbytes
, buffer
);
1354 rc
= assuan_send_data (ctx
, buffer
, nbytes
);
1356 return rc
; /* that is already an assuan error code */
1360 TEST_CARD_REMOVAL (ctrl
, rc
);
1365 /* PASSWD [--reset] [--nullpin] <chvno>
1367 Change the PIN or reset the retry counter of the card holder
1368 verfication vector CHVNO. The option --nullpin is used for TCOS
1369 cards to set the initial PIN. */
1371 cmd_passwd (assuan_context_t ctx
, char *line
)
1373 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1376 unsigned int flags
= 0;
1378 if (has_option (line
, "--reset"))
1379 flags
|= APP_CHANGE_FLAG_RESET
;
1380 if (has_option (line
, "--nullpin"))
1381 flags
|= APP_CHANGE_FLAG_NULLPIN
;
1383 if ( IS_LOCKED (ctrl
) )
1384 return gpg_error (GPG_ERR_LOCKED
);
1386 line
= skip_options (line
);
1389 return set_error (GPG_ERR_ASS_PARAMETER
, "no CHV number given");
1391 while (*line
&& !spacep (line
))
1395 if ((rc
= open_card (ctrl
, NULL
)))
1399 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1401 chvnostr
= xtrystrdup (chvnostr
);
1403 return out_of_core ();
1404 rc
= app_change_pin (ctrl
->app_ctx
, ctrl
, chvnostr
, flags
, pin_cb
, ctx
);
1406 log_error ("command passwd failed: %s\n", gpg_strerror (rc
));
1409 TEST_CARD_REMOVAL (ctrl
, rc
);
1416 Perform a VERIFY operation without doing anything else. This may
1417 be used to initialize a the PIN cache earlier to long lasting
1418 operations. Its use is highly application dependent.
1422 Perform a simple verify operation for CHV1 and CHV2, so that
1423 further operations won't ask for CHV2 and it is possible to do a
1424 cheap check on the PIN: If there is something wrong with the PIN
1425 entry system, only the regular CHV will get blocked and not the
1426 dangerous CHV3. IDSTR is the usual card's serial number in hex
1427 notation; an optional fingerprint part will get ignored. There
1428 is however a special mode if the IDSTR is sffixed with the
1429 literal string "[CHV3]": In this case the Admin PIN is checked
1430 if and only if the retry counter is still at 3.
1434 cmd_checkpin (assuan_context_t ctx
, char *line
)
1436 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1440 if ( IS_LOCKED (ctrl
) )
1441 return gpg_error (GPG_ERR_LOCKED
);
1443 if ((rc
= open_card (ctrl
, NULL
)))
1447 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1449 /* We have to use a copy of the key ID because the function may use
1450 the pin_cb which in turn uses the assuan line buffer and thus
1451 overwriting the original line with the keyid. */
1452 keyidstr
= xtrystrdup (line
);
1454 return out_of_core ();
1456 rc
= app_check_pin (ctrl
->app_ctx
,
1461 log_error ("app_check_pin failed: %s\n", gpg_strerror (rc
));
1463 TEST_CARD_REMOVAL (ctrl
, rc
);
1470 Grant exclusive card access to this session. Note that there is
1471 no lock counter used and a second lock from the same session will
1472 be ignored. A single unlock (or RESET) unlocks the session.
1473 Return GPG_ERR_LOCKED if another session has locked the reader.
1475 If the option --wait is given the command will wait until a
1476 lock has been released.
1479 cmd_lock (assuan_context_t ctx
, char *line
)
1481 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1487 if (locked_session
!= ctrl
->server_local
)
1488 rc
= gpg_error (GPG_ERR_LOCKED
);
1491 locked_session
= ctrl
->server_local
;
1494 if (rc
&& has_option (line
, "--wait"))
1497 pth_sleep (1); /* Better implement an event mechanism. However,
1498 for card operations this should be
1500 /* FIXME: Need to check that the connection is still alive.
1501 This can be done by issuing status messages. */
1504 #endif /*USE_GNU_PTH*/
1507 log_error ("cmd_lock failed: %s\n", gpg_strerror (rc
));
1514 Release exclusive card access.
1517 cmd_unlock (assuan_context_t ctx
, char *line
)
1519 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1526 if (locked_session
!= ctrl
->server_local
)
1527 rc
= gpg_error (GPG_ERR_LOCKED
);
1529 locked_session
= NULL
;
1532 rc
= gpg_error (GPG_ERR_NOT_LOCKED
);
1535 log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc
));
1542 Multi purpose command to return certain information.
1543 Supported values of WHAT are:
1545 version - Return the version of the program.
1546 pid - Return the process id of the server.
1548 socket_name - Return the name of the socket.
1550 status - Return the status of the current slot (in the future, may
1551 also return the status of all slots). The status is a list of
1552 one-character flags. The following flags are currently defined:
1553 'u' Usable card present. This is the normal state during operation.
1554 'r' Card removed. A reset is necessary.
1555 These flags are exclusive.
1557 reader_list - Return a list of detected card readers. Does
1558 currently only work with the internal CCID driver.
1562 cmd_getinfo (assuan_context_t ctx
, char *line
)
1566 if (!strcmp (line
, "version"))
1568 const char *s
= VERSION
;
1569 rc
= assuan_send_data (ctx
, s
, strlen (s
));
1571 else if (!strcmp (line
, "pid"))
1575 snprintf (numbuf
, sizeof numbuf
, "%lu", (unsigned long)getpid ());
1576 rc
= assuan_send_data (ctx
, numbuf
, strlen (numbuf
));
1578 else if (!strcmp (line
, "socket_name"))
1580 const char *s
= scd_get_socket_name ();
1583 rc
= assuan_send_data (ctx
, s
, strlen (s
));
1585 rc
= gpg_error (GPG_ERR_NO_DATA
);
1587 else if (!strcmp (line
, "status"))
1589 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1590 int slot
= ctrl
->reader_slot
;
1593 if (!ctrl
->server_local
->card_removed
&& slot
!= -1)
1595 struct slot_status_s
*ss
;
1597 if (!(slot
>= 0 && slot
< DIM(slot_table
)))
1600 ss
= &slot_table
[slot
];
1605 if (ss
->any
&& (ss
->status
& 1))
1608 rc
= assuan_send_data (ctx
, &flag
, 1);
1610 else if (!strcmp (line
, "reader_list"))
1613 char *s
= ccid_get_reader_list ();
1619 rc
= assuan_send_data (ctx
, s
, strlen (s
));
1621 rc
= gpg_error (GPG_ERR_NO_DATA
);
1625 rc
= set_error (GPG_ERR_ASS_PARAMETER
, "unknown value for WHAT");
1632 Restart the current connection; this is a kind of warm reset. It
1633 deletes the context used by this connection but does not send a
1634 RESET to the card. Thus the card itself won't get reset.
1636 This is used by gpg-agent to reuse a primary pipe connection and
1637 may be used by clients to backup from a conflict in the serial
1638 command; i.e. to select another application.
1642 cmd_restart (assuan_context_t ctx
, char *line
)
1644 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1650 release_application (ctrl
->app_ctx
);
1651 ctrl
->app_ctx
= NULL
;
1653 if (locked_session
&& ctrl
->server_local
== locked_session
)
1655 locked_session
= NULL
;
1656 log_info ("implicitly unlocking due to RESTART\n");
1664 Disconnect the card if it is not any longer used by other
1665 connections and the backend supports a disconnect operation.
1668 cmd_disconnect (assuan_context_t ctx
, char *line
)
1670 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1674 ctrl
->server_local
->disconnect_allowed
= 1;
1680 /* APDU [--atr] [--more] [hexstring]
1682 Send an APDU to the current reader. This command bypasses the high
1683 level functions and sends the data directly to the card. HEXSTRING
1684 is expected to be a proper APDU. If HEXSTRING is not given no
1685 commands are set to the card but the command will implictly check
1686 whether the card is ready for use.
1688 Using the option "--atr" returns the ATR of the card as a status
1689 message before any data like this:
1690 S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1
1692 Using the option --more handles the card status word MORE_DATA
1693 (61xx) and concatenate all reponses to one block.
1697 cmd_apdu (assuan_context_t ctx
, char *line
)
1699 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1701 unsigned char *apdu
;
1706 with_atr
= has_option (line
, "--atr");
1707 handle_more
= has_option (line
, "--more");
1709 line
= skip_options (line
);
1711 if ( IS_LOCKED (ctrl
) )
1712 return gpg_error (GPG_ERR_LOCKED
);
1714 if ((rc
= open_card (ctrl
, NULL
)))
1723 atr
= apdu_get_atr (ctrl
->reader_slot
, &atrlen
);
1724 if (!atr
|| atrlen
> sizeof hexbuf
- 2 )
1726 rc
= gpg_error (GPG_ERR_INV_CARD
);
1729 bin2hex (atr
, atrlen
, hexbuf
);
1731 send_status_info (ctrl
, "CARD-ATR", hexbuf
, strlen (hexbuf
), NULL
, 0);
1734 apdu
= hex_to_buffer (line
, &apdulen
);
1737 rc
= gpg_error_from_syserror ();
1742 unsigned char *result
= NULL
;
1745 rc
= apdu_send_direct (ctrl
->reader_slot
, apdu
, apdulen
, handle_more
,
1746 &result
, &resultlen
);
1748 log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc
));
1751 rc
= assuan_send_data (ctx
, result
, resultlen
);
1758 TEST_CARD_REMOVAL (ctrl
, rc
);
1766 /* Tell the assuan library about our commands */
1768 register_commands (assuan_context_t ctx
)
1772 int (*handler
)(assuan_context_t
, char *line
);
1774 { "SERIALNO", cmd_serialno
},
1775 { "LEARN", cmd_learn
},
1776 { "READCERT", cmd_readcert
},
1777 { "READKEY", cmd_readkey
},
1778 { "SETDATA", cmd_setdata
},
1779 { "PKSIGN", cmd_pksign
},
1780 { "PKAUTH", cmd_pkauth
},
1781 { "PKDECRYPT", cmd_pkdecrypt
},
1784 { "GETATTR", cmd_getattr
},
1785 { "SETATTR", cmd_setattr
},
1786 { "WRITECERT", cmd_writecert
},
1787 { "WRITEKEY", cmd_writekey
},
1788 { "GENKEY", cmd_genkey
},
1789 { "RANDOM", cmd_random
},
1790 { "PASSWD", cmd_passwd
},
1791 { "CHECKPIN", cmd_checkpin
},
1792 { "LOCK", cmd_lock
},
1793 { "UNLOCK", cmd_unlock
},
1794 { "GETINFO", cmd_getinfo
},
1795 { "RESTART", cmd_restart
},
1796 { "DISCONNECT", cmd_disconnect
},
1797 { "APDU", cmd_apdu
},
1802 for (i
=0; table
[i
].name
; i
++)
1804 rc
= assuan_register_command (ctx
, table
[i
].name
, table
[i
].handler
);
1808 assuan_set_hello_line (ctx
, "GNU Privacy Guard's Smartcard server ready");
1810 assuan_register_reset_notify (ctx
, reset_notify
);
1811 assuan_register_option_handler (ctx
, option_handler
);
1816 /* Startup the server. If FD is given as -1 this is simple pipe
1817 server, otherwise it is a regular server. Returns true if there
1818 are no more active asessions. */
1820 scd_command_handler (ctrl_t ctrl
, int fd
)
1823 assuan_context_t ctx
;
1831 rc
= assuan_init_pipe_server (&ctx
, filedes
);
1835 rc
= assuan_init_socket_server_ext (&ctx
, INT2FD(fd
), 2);
1839 log_error ("failed to initialize the server: %s\n",
1843 rc
= register_commands (ctx
);
1846 log_error ("failed to register commands with Assuan: %s\n",
1850 assuan_set_pointer (ctx
, ctrl
);
1852 /* Allocate and initialize the server object. Put it into the list
1853 of active sessions. */
1854 ctrl
->server_local
= xcalloc (1, sizeof *ctrl
->server_local
);
1855 ctrl
->server_local
->next_session
= session_list
;
1856 session_list
= ctrl
->server_local
;
1857 ctrl
->server_local
->ctrl_backlink
= ctrl
;
1858 ctrl
->server_local
->assuan_ctx
= ctx
;
1861 assuan_set_log_stream (ctx
, log_get_stream ());
1863 /* We open the reader right at startup so that the ticker is able to
1864 update the status file. */
1865 if (ctrl
->reader_slot
== -1)
1867 ctrl
->reader_slot
= get_reader_slot ();
1870 /* Command processing loop. */
1873 rc
= assuan_accept (ctx
);
1880 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc
));
1884 rc
= assuan_process (ctx
);
1887 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc
));
1892 /* Cleanup. We don't send an explicit reset to the card. */
1895 /* Release the server object. */
1896 if (session_list
== ctrl
->server_local
)
1897 session_list
= ctrl
->server_local
->next_session
;
1900 struct server_local_s
*sl
;
1902 for (sl
=session_list
; sl
->next_session
; sl
= sl
->next_session
)
1903 if (sl
->next_session
== ctrl
->server_local
)
1905 if (!sl
->next_session
)
1907 sl
->next_session
= ctrl
->server_local
->next_session
;
1909 xfree (ctrl
->server_local
);
1910 ctrl
->server_local
= NULL
;
1912 /* Release the Assuan context. */
1913 assuan_deinit_server (ctx
);
1915 /* If there are no more sessions return true. */
1916 return !session_list
;
1920 /* Send a line with status information via assuan and escape all given
1921 buffers. The variable elements are pairs of (char *, size_t),
1922 terminated with a (NULL, 0). */
1924 send_status_info (ctrl_t ctrl
, const char *keyword
, ...)
1927 const unsigned char *value
;
1931 assuan_context_t ctx
= ctrl
->server_local
->assuan_ctx
;
1933 va_start (arg_ptr
, keyword
);
1937 while ( (value
= va_arg (arg_ptr
, const unsigned char *)) )
1939 valuelen
= va_arg (arg_ptr
, size_t);
1941 continue; /* empty buffer */
1947 for ( ; valuelen
&& n
< DIM (buf
)-2; n
++, valuelen
--, value
++)
1949 if (*value
< ' ' || *value
== '+')
1951 sprintf (p
, "%%%02X", *value
);
1954 else if (*value
== ' ')
1961 assuan_write_status (ctx
, keyword
, buf
);
1968 /* Helper to send the clients a status change notification. */
1970 send_client_notifications (void)
1974 #ifdef HAVE_W32_SYSTEM
1982 struct server_local_s
*sl
;
1984 for (sl
=session_list
; sl
; sl
= sl
->next_session
)
1986 if (sl
->event_signal
&& sl
->assuan_ctx
)
1988 pid_t pid
= assuan_get_pid (sl
->assuan_ctx
);
1989 #ifdef HAVE_W32_SYSTEM
1990 HANDLE handle
= (void *)sl
->event_signal
;
1992 for (kidx
=0; kidx
< killidx
; kidx
++)
1993 if (killed
[kidx
].pid
== pid
1994 && killed
[kidx
].handle
== handle
)
1997 log_info ("event %lx (%p) already triggered for client %d\n",
1998 sl
->event_signal
, handle
, (int)pid
);
2001 log_info ("triggering event %lx (%p) for client %d\n",
2002 sl
->event_signal
, handle
, (int)pid
);
2003 if (!SetEvent (handle
))
2004 log_error ("SetEvent(%lx) failed: %s\n",
2005 sl
->event_signal
, w32_strerror (-1));
2006 if (killidx
< DIM (killed
))
2008 killed
[killidx
].pid
= pid
;
2009 killed
[killidx
].handle
= handle
;
2013 #else /*!HAVE_W32_SYSTEM*/
2014 int signo
= sl
->event_signal
;
2016 if (pid
!= (pid_t
)(-1) && pid
&& signo
> 0)
2018 for (kidx
=0; kidx
< killidx
; kidx
++)
2019 if (killed
[kidx
].pid
== pid
2020 && killed
[kidx
].signo
== signo
)
2023 log_info ("signal %d already sent to client %d\n",
2027 log_info ("sending signal %d to client %d\n",
2030 if (killidx
< DIM (killed
))
2032 killed
[killidx
].pid
= pid
;
2033 killed
[killidx
].signo
= signo
;
2037 #endif /*!HAVE_W32_SYSTEM*/
2045 /* This is the core of scd_update_reader_status_file but the caller
2046 needs to take care of the locking. */
2048 update_reader_status_file (int set_card_removed_flag
)
2051 unsigned int status
, changed
;
2053 /* Make sure that the reader has been opened. Like get_reader_slot,
2054 this part of the code assumes that there is only one reader. */
2055 if (!slot_table
[0].valid
)
2056 (void)get_reader_slot ();
2058 /* Note, that we only try to get the status, because it does not
2059 make sense to wait here for a operation to complete. If we are
2060 busy working with a card, delays in the status file update should
2062 for (idx
=0; idx
< DIM(slot_table
); idx
++)
2064 struct slot_status_s
*ss
= slot_table
+ idx
;
2065 struct server_local_s
*sl
;
2068 if (!ss
->valid
|| ss
->slot
== -1)
2069 continue; /* Not valid or reader not yet open. */
2071 sw_apdu
= apdu_get_status (ss
->slot
, 0, &status
, &changed
);
2074 /* Get status failed. Ignore that. */
2078 if (!ss
->any
|| ss
->status
!= status
|| ss
->changed
!= changed
)
2084 log_info ("updating slot %d status: 0x%04X->0x%04X (%u->%u)\n",
2085 ss
->slot
, ss
->status
, status
, ss
->changed
, changed
);
2086 ss
->status
= status
;
2087 ss
->changed
= changed
;
2089 /* FIXME: Should this be IDX instead of ss->slot? This
2090 depends on how client sessions will associate the reader
2091 status with their session. */
2092 snprintf (templ
, sizeof templ
, "reader_%d.status", ss
->slot
);
2093 fname
= make_filename (opt
.homedir
, templ
, NULL
);
2094 fp
= fopen (fname
, "w");
2097 fprintf (fp
, "%s\n",
2098 (status
& 1)? "USABLE":
2099 (status
& 4)? "ACTIVE":
2100 (status
& 2)? "PRESENT": "NOCARD");
2105 /* If a status script is executable, run it. */
2107 const char *args
[9], *envs
[2];
2108 char numbuf1
[30], numbuf2
[30], numbuf3
[30];
2109 char *homestr
, *envstr
;
2112 homestr
= make_filename (opt
.homedir
, NULL
);
2113 if (estream_asprintf (&envstr
, "GNUPGHOME=%s", homestr
) < 0)
2114 log_error ("out of core while building environment\n");
2120 sprintf (numbuf1
, "%d", ss
->slot
);
2121 sprintf (numbuf2
, "0x%04X", ss
->status
);
2122 sprintf (numbuf3
, "0x%04X", status
);
2123 args
[0] = "--reader-port";
2125 args
[2] = "--old-code";
2127 args
[4] = "--new-code";
2129 args
[6] = "--status";
2130 args
[7] = ((status
& 1)? "USABLE":
2131 (status
& 4)? "ACTIVE":
2132 (status
& 2)? "PRESENT": "NOCARD");
2135 fname
= make_filename (opt
.homedir
, "scd-event", NULL
);
2136 err
= gnupg_spawn_process_detached (fname
, args
, envs
);
2137 if (err
&& gpg_err_code (err
) != GPG_ERR_ENOENT
)
2138 log_error ("failed to run event handler `%s': %s\n",
2139 fname
, gpg_strerror (err
));
2146 /* Set the card removed flag for all current sessions. We
2147 will set this on any card change because a reset or
2148 SERIALNO request must be done in any case. */
2149 if (ss
->any
&& set_card_removed_flag
)
2150 update_card_removed (idx
, 1);
2154 /* Send a signal to all clients who applied for it. */
2155 send_client_notifications ();
2158 /* Check whether a disconnect is pending. */
2159 if (opt
.card_timeout
)
2161 for (sl
=session_list
; sl
; sl
= sl
->next_session
)
2162 if (!sl
->disconnect_allowed
)
2164 if (session_list
&& !sl
)
2166 /* FIXME: Use a real timeout. */
2167 /* At least one connection and all allow a disconnect. */
2168 log_info ("disconnecting card in slot %d\n", ss
->slot
);
2169 apdu_disconnect (ss
->slot
);
2176 /* This function is called by the ticker thread to check for changes
2177 of the reader stati. It updates the reader status files and if
2178 requested by the caller also send a signal to the caller. */
2180 scd_update_reader_status_file (void)
2182 if (!pth_mutex_acquire (&status_file_update_lock
, 1, NULL
))
2183 return; /* locked - give up. */
2184 update_reader_status_file (1);
2185 if (!pth_mutex_release (&status_file_update_lock
))
2186 log_error ("failed to release status_file_update lock\n");