1 /* command.c - SCdaemon command handler
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3 * 2007, 2008, 2009, 2011 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/>.
36 #include "app-common.h"
38 #include "apdu.h" /* Required for apdu_*_reader (). */
42 #include "ccid-driver.h"
45 #include "server-help.h"
47 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
48 #define MAXLEN_PIN 100
50 /* Maximum allowed size of key data as used in inquiries. */
51 #define MAXLEN_KEYDATA 4096
53 /* Maximum allowed total data size for SETDATA. */
54 #define MAXLEN_SETDATA 4096
56 /* Maximum allowed size of certificate data as used in inquiries. */
57 #define MAXLEN_CERTDATA 16384
60 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
63 /* Macro to flag a removed card. ENODEV is also tested to catch the
64 case of a removed reader. */
65 #define TEST_CARD_REMOVAL(c,r) \
68 if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \
69 || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED \
70 || gpg_err_code (_r) == GPG_ERR_CARD_RESET \
71 || gpg_err_code (_r) == GPG_ERR_ENODEV ) \
72 update_card_removed ((c)->server_local->vreader_idx, 1); \
75 #define IS_LOCKED(c) \
77 && locked_session != (c)->server_local \
78 && (c)->server_local->vreader_idx != -1 \
79 && locked_session->ctrl_backlink \
80 && ((c)->server_local->vreader_idx \
81 == locked_session->ctrl_backlink->server_local->vreader_idx))
84 /* This structure is used to keep track of user readers. To
85 eventually accommodate this structure for RFID cards, where more
86 than one card is used per reader, we name it virtual reader. */
89 int valid; /* True if the other objects are valid. */
90 int slot; /* APDU slot number of the reader or -1 if not open. */
92 int reset_failed; /* A reset failed. */
94 int any; /* Flag indicating whether any status check has been
95 done. This is set once to indicate that the status
96 tracking for the slot has been initialized. */
97 unsigned int status; /* Last status of the reader. */
98 unsigned int changed; /* Last change counter of the reader. */
102 /* Data used to associate an Assuan context with local server data.
103 This object describes the local properties of one session. */
104 struct server_local_s
106 /* We keep a list of all active sessions with the anchor at
107 SESSION_LIST (see below). This field is used for linking. */
108 struct server_local_s *next_session;
110 /* This object is usually assigned to a CTRL object (which is
111 globally visible). While enumerating all sessions we sometimes
112 need to access data of the CTRL object; thus we keep a
114 ctrl_t ctrl_backlink;
116 /* The Assuan context used by this session/server. */
117 assuan_context_t assuan_ctx;
119 #ifdef HAVE_W32_SYSTEM
120 unsigned long event_signal; /* Or 0 if not used. */
122 int event_signal; /* Or 0 if not used. */
125 /* Index into the vreader table (command.c) or -1 if not open. */
128 /* True if the card has been removed and a reset is required to
129 continue operation. */
132 /* A disconnect command has been sent. */
133 int disconnect_allowed;
135 /* If set to true we will be terminate ourself at the end of the
142 /* The table with information on all used virtual readers. */
143 static struct vreader_s vreader_table[10];
146 /* To keep track of all running sessions, we link all active server
147 contexts and the anchor in this variable. */
148 static struct server_local_s *session_list;
150 /* If a session has been locked we store a link to its server object
152 static struct server_local_s *locked_session;
154 /* While doing a reset we need to make sure that the ticker does not
155 call scd_update_reader_status_file while we are using it. */
156 static npth_mutex_t status_file_update_lock;
159 /*-- Local prototypes --*/
160 static void update_reader_status_file (int set_card_removed_flag);
165 /* This function must be called once to initialize this module. This
166 has to be done before a second thread is spawned. We can't do the
167 static initialization because Pth emulation code might not be able
168 to do a static init; in particular, it is not possible for W32. */
170 initialize_module_command (void)
172 static int initialized;
177 err = npth_mutex_init (&status_file_update_lock, NULL);
184 /* Helper to return the slot number for a given virtual reader index
185 VRDR. In case on an error -1 is returned. */
187 vreader_slot (int vrdr)
189 if (vrdr == -1 || !(vrdr >= 0 && vrdr < DIM(vreader_table)))
191 if (!vreader_table [vrdr].valid)
193 return vreader_table[vrdr].slot;
197 /* Update the CARD_REMOVED element of all sessions using the virtual
198 reader given by VRDR to VALUE. */
200 update_card_removed (int vrdr, int value)
202 struct server_local_s *sl;
207 for (sl=session_list; sl; sl = sl->next_session)
209 ctrl_t ctrl = sl->ctrl_backlink;
211 if (ctrl && ctrl->server_local->vreader_idx == vrdr)
213 sl->card_removed = value;
216 struct app_ctx_s *app = ctrl->app_ctx;
217 ctrl->app_ctx = NULL;
218 release_application (app);
223 /* Let the card application layer know about the removal. */
226 log_debug ("Removal of a card: %d\n", vrdr);
227 application_notify_card_reset (vreader_slot (vrdr));
228 vreader_table[vrdr].slot = -1;
233 /* Convert the STRING into a newly allocated buffer while translating
234 the hex numbers. Stops at the first invalid character. Blanks and
235 colons are allowed to separate the hex digits. Returns NULL on
236 error or a newly malloced buffer and its length in LENGTH. */
237 static unsigned char *
238 hex_to_buffer (const char *string, size_t *r_length)
240 unsigned char *buffer;
244 buffer = xtrymalloc (strlen (string)+1);
247 for (s=string, n=0; *s; s++)
249 if (spacep (s) || *s == ':')
251 if (hexdigitp (s) && hexdigitp (s+1))
253 buffer[n++] = xtoi_2 (s);
265 /* Reset the card and free the application context. With SEND_RESET
266 set to true actually send a RESET to the reader; this is the normal
267 way of calling the function. */
269 do_reset (ctrl_t ctrl, int send_reset)
271 int vrdr = ctrl->server_local->vreader_idx;
274 struct app_ctx_s *app = ctrl->app_ctx;
276 if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table))))
279 /* If there is an active application, release it. */
282 ctrl->app_ctx = NULL;
283 release_application (app);
286 /* Release the same application which is used by other sessions. */
289 struct server_local_s *sl;
291 for (sl=session_list; sl; sl = sl->next_session)
293 ctrl_t c = sl->ctrl_backlink;
295 if (c && c != ctrl && c->server_local->vreader_idx == vrdr)
297 struct app_ctx_s *app0 = c->app_ctx;
301 release_application (app0);
307 /* If we want a real reset for the card, send the reset APDU and
308 tell the application layer about it. */
309 slot = vreader_slot (vrdr);
310 if (slot != -1 && send_reset && !IS_LOCKED (ctrl) )
312 application_notify_card_reset (slot);
313 switch (apdu_reset (slot))
317 case SW_HOST_NO_CARD:
318 case SW_HOST_CARD_INACTIVE:
321 apdu_close_reader (slot);
322 vreader_table[vrdr].slot = -1;
327 /* If we hold a lock, unlock now. */
328 if (locked_session && ctrl->server_local == locked_session)
330 locked_session = NULL;
331 log_info ("implicitly unlocking due to RESET\n");
334 /* Reset the card removed flag for the current reader. We need to
335 take the lock here so that the ticker thread won't concurrently
336 try to update the file. Calling update_reader_status_file is
337 required to get hold of the new status of the card in the vreader
339 err = npth_mutex_lock (&status_file_update_lock);
342 log_error ("failed to acquire status_file_update lock\n");
343 ctrl->server_local->vreader_idx = -1;
346 update_reader_status_file (0); /* Update slot status table. */
347 update_card_removed (vrdr, 0); /* Clear card_removed flag. */
348 err = npth_mutex_unlock (&status_file_update_lock);
350 log_error ("failed to release status_file_update lock: %s\n",
353 /* Do this last, so that the update_card_removed above does its job. */
354 ctrl->server_local->vreader_idx = -1;
359 reset_notify (assuan_context_t ctx, char *line)
361 ctrl_t ctrl = assuan_get_pointer (ctx);
371 option_handler (assuan_context_t ctx, const char *key, const char *value)
373 ctrl_t ctrl = assuan_get_pointer (ctx);
375 if (!strcmp (key, "event-signal"))
377 /* A value of 0 is allowed to reset the event signal. */
378 #ifdef HAVE_W32_SYSTEM
380 return gpg_error (GPG_ERR_ASS_PARAMETER);
381 ctrl->server_local->event_signal = strtoul (value, NULL, 16);
383 int i = *value? atoi (value) : -1;
385 return gpg_error (GPG_ERR_ASS_PARAMETER);
386 ctrl->server_local->event_signal = i;
394 /* Return the index of the current reader or open the reader if no
395 other sessions are using that reader. If it is not possible to
396 open the reader -1 is returned. Note, that we currently support
397 only one reader but most of the code (except for this function)
398 should be able to cope with several readers. */
400 get_current_reader (void)
402 struct vreader_s *vr;
404 /* We only support one reader for now. */
405 vr = &vreader_table[0];
407 /* Initialize the vreader item if not yet done. */
414 /* Try to open the reader. */
417 vr->slot = apdu_open_reader (opt.reader_port);
419 /* If we still don't have a slot, we have no readers.
420 Invalidate for now until a reader is attached. */
427 /* Return the vreader index or -1. */
428 return vr->valid ? 0 : -1;
432 /* If the card has not yet been opened, do it. */
434 open_card (ctrl_t ctrl, const char *apptype)
439 /* If we ever got a card not present error code, return that. Only
440 the SERIALNO command and a reset are able to clear from that
442 if (ctrl->server_local->card_removed)
443 return gpg_error (GPG_ERR_CARD_REMOVED);
445 if ( IS_LOCKED (ctrl) )
446 return gpg_error (GPG_ERR_LOCKED);
448 /* If we are already initialized for one specific application we
449 need to check that the client didn't requested a specific
450 application different from the one in use before we continue. */
453 return check_application_conflict
454 (ctrl, vreader_slot (ctrl->server_local->vreader_idx), apptype);
457 /* Setup the vreader and select the application. */
458 if (ctrl->server_local->vreader_idx != -1)
459 vrdr = ctrl->server_local->vreader_idx;
461 vrdr = get_current_reader ();
462 ctrl->server_local->vreader_idx = vrdr;
464 err = gpg_error (GPG_ERR_CARD);
467 /* Fixme: We should move the apdu_connect call to
468 select_application. */
470 int slot = vreader_slot (vrdr);
472 ctrl->server_local->disconnect_allowed = 0;
473 sw = apdu_connect (slot);
474 if (sw && sw != SW_HOST_ALREADY_CONNECTED)
476 if (sw == SW_HOST_NO_CARD)
477 err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
478 else if (sw == SW_HOST_CARD_INACTIVE)
479 err = gpg_error (GPG_ERR_CARD_RESET);
481 err = gpg_error (GPG_ERR_ENODEV);
484 err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
487 TEST_CARD_REMOVAL (ctrl, err);
492 static const char hlp_serialno[] =
493 "SERIALNO [<apptype>]\n"
495 "Return the serial number of the card using a status response. This\n"
496 "function should be used to check for the presence of a card.\n"
498 "If APPTYPE is given, an application of that type is selected and an\n"
499 "error is returned if the application is not supported or available.\n"
500 "The default is to auto-select the application using a hardwired\n"
501 "preference system. Note, that a future extension to this function\n"
502 "may enable specifying a list and order of applications to try.\n"
504 "This function is special in that it can be used to reset the card.\n"
505 "Most other functions will return an error when a card change has\n"
506 "been detected and the use of this function is therefore required.\n"
508 "Background: We want to keep the client clear of handling card\n"
509 "changes between operations; i.e. the client can assume that all\n"
510 "operations are done on the same card unless he calls this function.";
512 cmd_serialno (assuan_context_t ctx, char *line)
514 ctrl_t ctrl = assuan_get_pointer (ctx);
520 /* Clear the remove flag so that the open_card is able to reread it. */
522 if (ctrl->server_local->card_removed)
524 if ( IS_LOCKED (ctrl) )
525 return gpg_error (GPG_ERR_LOCKED);
529 if ((rc = open_card (ctrl, *line? line:NULL)))
531 /* In case of an inactive card, retry once. */
532 if (gpg_err_code (rc) == GPG_ERR_CARD_RESET && retries++ < 1)
537 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
541 rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
542 serial, (unsigned long)stamp);
548 static const char hlp_learn[] =
549 "LEARN [--force] [--keypairinfo]\n"
551 "Learn all useful information of the currently inserted card. When\n"
552 "used without the force options, the command might do an INQUIRE\n"
555 " INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>\n"
557 "The client should just send an \"END\" if the processing should go on\n"
558 "or a \"CANCEL\" to force the function to terminate with a Cancel\n"
561 "With the option --keypairinfo only KEYPARIINFO lstatus lines are\n"
564 "The response of this command is a list of status lines formatted as\n"
567 " S APPTYPE <apptype>\n"
569 "This returns the type of the application, currently the strings:\n"
571 " P15 = PKCS-15 structure used\n"
572 " DINSIG = DIN SIG\n"
573 " OPENPGP = OpenPGP card\n"
574 " NKS = NetKey card\n"
576 "are implemented. These strings are aliases for the AID\n"
578 " S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>\n"
580 "If there is no certificate yet stored on the card a single 'X' is\n"
581 "returned as the keygrip. In addition to the keypair info, information\n"
582 "about all certificates stored on the card is also returned:\n"
584 " S CERTINFO <certtype> <hexstring_with_id>\n"
586 "Where CERTTYPE is a number indicating the type of certificate:\n"
588 " 100 := Regular X.509 cert\n"
589 " 101 := Trusted X.509 cert\n"
590 " 102 := Useful X.509 cert\n"
591 " 110 := Root CA cert in a special format (e.g. DINSIG)\n"
592 " 111 := Root CA cert as standard X509 cert.\n"
594 "For certain cards, more information will be returned:\n"
596 " S KEY-FPR <no> <hexstring>\n"
598 "For OpenPGP cards this returns the stored fingerprints of the\n"
599 "keys. This can be used check whether a key is available on the\n"
600 "card. NO may be 1, 2 or 3.\n"
602 " S CA-FPR <no> <hexstring>\n"
604 "Similar to above, these are the fingerprints of keys assumed to be\n"
605 "ultimately trusted.\n"
607 " S DISP-NAME <name_of_card_holder>\n"
609 "The name of the card holder as stored on the card; percent\n"
610 "escaping takes place, spaces are encoded as '+'\n"
612 " S PUBKEY-URL <url>\n"
614 "The URL to be used for locating the entire public key.\n"
616 "Note, that this function may even be used on a locked card.";
618 cmd_learn (assuan_context_t ctx, char *line)
620 ctrl_t ctrl = assuan_get_pointer (ctx);
622 int only_keypairinfo = has_option (line, "--keypairinfo");
624 if ((rc = open_card (ctrl, NULL)))
627 /* Unless the force option is used we try a shortcut by identifying
628 the card using a serial number and inquiring the client with
629 that. The client may choose to cancel the operation if he already
630 knows about this card */
631 if (!only_keypairinfo)
638 slot = vreader_slot (ctrl->server_local->vreader_idx);
639 reader = apdu_get_reader_name (slot);
641 return out_of_core ();
642 send_status_direct (ctrl, "READER", reader);
643 /* No need to free the string of READER. */
645 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
649 rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
650 serial, (unsigned long)stamp);
654 return out_of_core ();
657 if (!has_option (line, "--force"))
661 rc = gpgrt_asprintf (&command, "KNOWNCARDP %s %lu",
662 serial, (unsigned long)stamp);
666 return out_of_core ();
668 rc = assuan_inquire (ctx, command, NULL, NULL, 0);
672 if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
673 log_error ("inquire KNOWNCARDP failed: %s\n",
678 /* Not canceled, so we have to proceeed. */
683 /* Let the application print out its collection of useful status
686 rc = app_write_learn_status (ctrl->app_ctx, ctrl, only_keypairinfo);
688 TEST_CARD_REMOVAL (ctrl, rc);
694 static const char hlp_readcert[] =
695 "READCERT <hexified_certid>|<keyid>\n"
697 "Note, that this function may even be used on a locked card.";
699 cmd_readcert (assuan_context_t ctx, char *line)
701 ctrl_t ctrl = assuan_get_pointer (ctx);
706 if ((rc = open_card (ctrl, NULL)))
709 line = xstrdup (line); /* Need a copy of the line. */
710 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
712 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
717 rc = assuan_send_data (ctx, cert, ncert);
723 TEST_CARD_REMOVAL (ctrl, rc);
728 static const char hlp_readkey[] =
731 "Return the public key for the given cert or key ID as a standard\n"
734 "Note, that this function may even be used on a locked card.";
736 cmd_readkey (assuan_context_t ctx, char *line)
738 ctrl_t ctrl = assuan_get_pointer (ctx);
740 unsigned char *cert = NULL;
742 ksba_cert_t kc = NULL;
747 if ((rc = open_card (ctrl, NULL)))
750 line = xstrdup (line); /* Need a copy of the line. */
751 /* If the application supports the READKEY function we use that.
752 Otherwise we use the old way by extracting it from the
754 rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen);
756 { /* Yeah, got that key - send it back. */
757 rc = assuan_send_data (ctx, pk, pklen);
764 if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
765 log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
768 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
770 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
777 rc = ksba_cert_new (&kc);
781 rc = ksba_cert_init_from_mem (kc, cert, ncert);
784 log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
788 p = ksba_cert_get_public_key (kc);
791 rc = gpg_error (GPG_ERR_NO_PUBKEY);
795 n = gcry_sexp_canon_len (p, 0, NULL, NULL);
796 rc = assuan_send_data (ctx, p, n);
801 ksba_cert_release (kc);
803 TEST_CARD_REMOVAL (ctrl, rc);
809 static const char hlp_setdata[] =
810 "SETDATA [--append] <hexstring>\n"
812 "The client should use this command to tell us the data he want to sign.\n"
813 "With the option --append, the data is appended to the data set by a\n"
814 "previous SETDATA command.";
816 cmd_setdata (assuan_context_t ctx, char *line)
818 ctrl_t ctrl = assuan_get_pointer (ctx);
824 append = (ctrl->in_data.value && has_option (line, "--append"));
826 line = skip_options (line);
828 if (locked_session && locked_session != ctrl->server_local)
829 return gpg_error (GPG_ERR_LOCKED);
831 /* Parse the hexstring. */
832 for (p=line,n=0; hexdigitp (p); p++, n++)
835 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
837 return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
839 return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
843 if (ctrl->in_data.valuelen + n > MAXLEN_SETDATA)
844 return set_error (GPG_ERR_TOO_LARGE,
845 "limit on total size of data reached");
846 buf = xtrymalloc (ctrl->in_data.valuelen + n);
849 buf = xtrymalloc (n);
851 return out_of_core ();
855 memcpy (buf, ctrl->in_data.value, ctrl->in_data.valuelen);
856 off = ctrl->in_data.valuelen;
860 for (p=line, i=0; i < n; p += 2, i++)
861 buf[off+i] = xtoi_2 (p);
863 xfree (ctrl->in_data.value);
864 ctrl->in_data.value = buf;
865 ctrl->in_data.valuelen = off+n;
872 pin_cb (void *opaque, const char *info, char **retstr)
874 assuan_context_t ctx = opaque;
877 unsigned char *value;
882 /* We prompt for pinpad entry. To make sure that the popup has
883 been show we use an inquire and not just a status message.
884 We ignore any value returned. */
887 log_debug ("prompting for pinpad entry '%s'\n", info);
888 rc = gpgrt_asprintf (&command, "POPUPPINPADPROMPT %s", info);
890 return gpg_error (gpg_err_code_from_errno (errno));
891 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
896 log_debug ("dismiss pinpad entry prompt\n");
897 rc = assuan_inquire (ctx, "DISMISSPINPADPROMPT",
898 &value, &valuelen, MAXLEN_PIN);
906 log_debug ("asking for PIN '%s'\n", info);
908 rc = gpgrt_asprintf (&command, "NEEDPIN %s", info);
910 return gpg_error (gpg_err_code_from_errno (errno));
912 /* Fixme: Write an inquire function which returns the result in
913 secure memory and check all further handling of the PIN. */
914 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
919 if (!valuelen || value[valuelen-1])
921 /* We require that the returned value is an UTF-8 string */
923 return gpg_error (GPG_ERR_INV_RESPONSE);
925 *retstr = (char*)value;
930 static const char hlp_pksign[] =
931 "PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5]] <hexified_id>\n"
933 "The --hash option is optional; the default is SHA1.";
935 cmd_pksign (assuan_context_t ctx, char *line)
937 ctrl_t ctrl = assuan_get_pointer (ctx);
939 unsigned char *outdata;
944 if (has_option (line, "--hash=rmd160"))
945 hash_algo = GCRY_MD_RMD160;
946 else if (has_option (line, "--hash=sha1"))
947 hash_algo = GCRY_MD_SHA1;
948 else if (has_option (line, "--hash=sha224"))
949 hash_algo = GCRY_MD_SHA224;
950 else if (has_option (line, "--hash=sha256"))
951 hash_algo = GCRY_MD_SHA256;
952 else if (has_option (line, "--hash=sha384"))
953 hash_algo = GCRY_MD_SHA384;
954 else if (has_option (line, "--hash=sha512"))
955 hash_algo = GCRY_MD_SHA512;
956 else if (has_option (line, "--hash=md5"))
957 hash_algo = GCRY_MD_MD5;
958 else if (!strstr (line, "--"))
959 hash_algo = GCRY_MD_SHA1;
961 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
963 line = skip_options (line);
965 if ( IS_LOCKED (ctrl) )
966 return gpg_error (GPG_ERR_LOCKED);
968 if ((rc = open_card (ctrl, NULL)))
971 /* We have to use a copy of the key ID because the function may use
972 the pin_cb which in turn uses the assuan line buffer and thus
973 overwriting the original line with the keyid */
974 keyidstr = xtrystrdup (line);
976 return out_of_core ();
978 rc = app_sign (ctrl->app_ctx,
981 ctrl->in_data.value, ctrl->in_data.valuelen,
982 &outdata, &outdatalen);
987 log_error ("app_sign failed: %s\n", gpg_strerror (rc));
991 rc = assuan_send_data (ctx, outdata, outdatalen);
994 return rc; /* that is already an assuan error code */
997 TEST_CARD_REMOVAL (ctrl, rc);
1002 static const char hlp_pkauth[] =
1003 "PKAUTH <hexified_id>";
1005 cmd_pkauth (assuan_context_t ctx, char *line)
1007 ctrl_t ctrl = assuan_get_pointer (ctx);
1009 unsigned char *outdata;
1013 if ( IS_LOCKED (ctrl) )
1014 return gpg_error (GPG_ERR_LOCKED);
1016 if ((rc = open_card (ctrl, NULL)))
1020 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1022 /* We have to use a copy of the key ID because the function may use
1023 the pin_cb which in turn uses the assuan line buffer and thus
1024 overwriting the original line with the keyid */
1025 keyidstr = xtrystrdup (line);
1027 return out_of_core ();
1029 rc = app_auth (ctrl->app_ctx,
1032 ctrl->in_data.value, ctrl->in_data.valuelen,
1033 &outdata, &outdatalen);
1037 log_error ("app_auth failed: %s\n", gpg_strerror (rc));
1041 rc = assuan_send_data (ctx, outdata, outdatalen);
1044 return rc; /* that is already an assuan error code */
1047 TEST_CARD_REMOVAL (ctrl, rc);
1052 static const char hlp_pkdecrypt[] =
1053 "PKDECRYPT <hexified_id>";
1055 cmd_pkdecrypt (assuan_context_t ctx, char *line)
1057 ctrl_t ctrl = assuan_get_pointer (ctx);
1059 unsigned char *outdata;
1062 unsigned int infoflags;
1064 if ( IS_LOCKED (ctrl) )
1065 return gpg_error (GPG_ERR_LOCKED);
1067 if ((rc = open_card (ctrl, NULL)))
1070 keyidstr = xtrystrdup (line);
1072 return out_of_core ();
1073 rc = app_decipher (ctrl->app_ctx,
1076 ctrl->in_data.value, ctrl->in_data.valuelen,
1077 &outdata, &outdatalen, &infoflags);
1082 log_error ("app_decipher failed: %s\n", gpg_strerror (rc));
1086 /* If the card driver told us that there is no padding, send a
1087 status line. If there is a padding it is assumed that the
1088 caller knows what padding is used. It would have been better
1089 to always send that information but for backward
1090 compatibility we can't do that. */
1091 if ((infoflags & APP_DECIPHER_INFO_NOPAD))
1092 send_status_direct (ctrl, "PADDING", "0");
1093 rc = assuan_send_data (ctx, outdata, outdatalen);
1096 return rc; /* that is already an assuan error code */
1099 TEST_CARD_REMOVAL (ctrl, rc);
1104 static const char hlp_getattr[] =
1107 "This command is used to retrieve data from a smartcard. The\n"
1108 "allowed names depend on the currently selected smartcard\n"
1109 "application. NAME must be percent and '+' escaped. The value is\n"
1110 "returned through status message, see the LEARN command for details.\n"
1112 "However, the current implementation assumes that Name is not escaped;\n"
1113 "this works as long as no one uses arbitrary escaping. \n"
1115 "Note, that this function may even be used on a locked card.";
1117 cmd_getattr (assuan_context_t ctx, char *line)
1119 ctrl_t ctrl = assuan_get_pointer (ctx);
1121 const char *keyword;
1123 if ((rc = open_card (ctrl, NULL)))
1127 for (; *line && !spacep (line); line++)
1132 /* (We ignore any garbage for now.) */
1134 /* FIXME: Applications should not return sensitive data if the card
1136 rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
1138 TEST_CARD_REMOVAL (ctrl, rc);
1143 static const char hlp_setattr[] =
1144 "SETATTR <name> <value> \n"
1146 "This command is used to store data on a a smartcard. The allowed\n"
1147 "names and values are depend on the currently selected smartcard\n"
1148 "application. NAME and VALUE must be percent and '+' escaped.\n"
1150 "However, the current implementation assumes that NAME is not\n"
1151 "escaped; this works as long as no one uses arbitrary escaping.\n"
1153 "A PIN will be requested for most NAMEs. See the corresponding\n"
1154 "setattr function of the actually used application (app-*.c) for\n"
1157 cmd_setattr (assuan_context_t ctx, char *orig_line)
1159 ctrl_t ctrl = assuan_get_pointer (ctx);
1164 char *line, *linebuf;
1166 if ( IS_LOCKED (ctrl) )
1167 return gpg_error (GPG_ERR_LOCKED);
1169 if ((rc = open_card (ctrl, NULL)))
1172 /* We need to use a copy of LINE, because PIN_CB uses the same
1173 context and thus reuses the Assuan provided LINE. */
1174 line = linebuf = xtrystrdup (orig_line);
1176 return out_of_core ();
1179 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1183 while (spacep (line))
1185 nbytes = percent_plus_unescape_inplace (line, 0);
1187 rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx,
1188 (const unsigned char*)line, nbytes);
1191 TEST_CARD_REMOVAL (ctrl, rc);
1196 static const char hlp_writecert[] =
1197 "WRITECERT <hexified_certid>\n"
1199 "This command is used to store a certifciate on a smartcard. The\n"
1200 "allowed certids depend on the currently selected smartcard\n"
1201 "application. The actual certifciate is requested using the inquiry\n"
1202 "\"CERTDATA\" and needs to be provided in its raw (e.g. DER) form.\n"
1204 "In almost all cases a a PIN will be requested. See the related\n"
1205 "writecert function of the actually used application (app-*.c) for\n"
1208 cmd_writecert (assuan_context_t ctx, char *line)
1210 ctrl_t ctrl = assuan_get_pointer (ctx);
1213 unsigned char *certdata;
1216 if ( IS_LOCKED (ctrl) )
1217 return gpg_error (GPG_ERR_LOCKED);
1219 line = skip_options (line);
1222 return set_error (GPG_ERR_ASS_PARAMETER, "no certid given");
1224 while (*line && !spacep (line))
1228 if ((rc = open_card (ctrl, NULL)))
1232 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1234 certid = xtrystrdup (certid);
1236 return out_of_core ();
1238 /* Now get the actual keydata. */
1239 rc = assuan_inquire (ctx, "CERTDATA",
1240 &certdata, &certdatalen, MAXLEN_CERTDATA);
1247 /* Write the certificate to the card. */
1248 rc = app_writecert (ctrl->app_ctx, ctrl, certid,
1249 pin_cb, ctx, certdata, certdatalen);
1253 TEST_CARD_REMOVAL (ctrl, rc);
1258 static const char hlp_writekey[] =
1259 "WRITEKEY [--force] <keyid> \n"
1261 "This command is used to store a secret key on a a smartcard. The\n"
1262 "allowed keyids depend on the currently selected smartcard\n"
1263 "application. The actual keydata is requested using the inquiry\n"
1264 "\"KEYDATA\" and need to be provided without any protection. With\n"
1265 "--force set an existing key under this KEYID will get overwritten.\n"
1266 "The keydata is expected to be the usual canonical encoded\n"
1269 "A PIN will be requested for most NAMEs. See the corresponding\n"
1270 "writekey function of the actually used application (app-*.c) for\n"
1273 cmd_writekey (assuan_context_t ctx, char *line)
1275 ctrl_t ctrl = assuan_get_pointer (ctx);
1278 int force = has_option (line, "--force");
1279 unsigned char *keydata;
1282 if ( IS_LOCKED (ctrl) )
1283 return gpg_error (GPG_ERR_LOCKED);
1285 line = skip_options (line);
1288 return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1290 while (*line && !spacep (line))
1294 if ((rc = open_card (ctrl, NULL)))
1298 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1300 keyid = xtrystrdup (keyid);
1302 return out_of_core ();
1304 /* Now get the actual keydata. */
1305 assuan_begin_confidential (ctx);
1306 rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1307 assuan_end_confidential (ctx);
1314 /* Write the key to the card. */
1315 rc = app_writekey (ctrl->app_ctx, ctrl, keyid, force? 1:0,
1316 pin_cb, ctx, keydata, keydatalen);
1320 TEST_CARD_REMOVAL (ctrl, rc);
1325 static const char hlp_genkey[] =
1326 "GENKEY [--force] [--timestamp=<isodate>] <no>\n"
1328 "Generate a key on-card identified by NO, which is application\n"
1329 "specific. Return values are application specific. For OpenPGP\n"
1330 "cards 3 status lines are returned:\n"
1332 " S KEY-FPR <hexstring>\n"
1333 " S KEY-CREATED-AT <seconds_since_epoch>\n"
1334 " S KEY-DATA [-|p|n] <hexdata>\n"
1336 " 'p' and 'n' are the names of the RSA parameters; '-' is used to\n"
1337 " indicate that HEXDATA is the first chunk of a parameter given\n"
1338 " by the next KEY-DATA.\n"
1340 "--force is required to overwrite an already existing key. The\n"
1341 "KEY-CREATED-AT is required for further processing because it is\n"
1342 "part of the hashed key material for the fingerprint.\n"
1344 "If --timestamp is given an OpenPGP key will be created using this\n"
1345 "value. The value needs to be in ISO Format; e.g.\n"
1346 "\"--timestamp=20030316T120000\" and after 1970-01-01 00:00:00.\n"
1348 "The public part of the key can also later be retrieved using the\n"
1351 cmd_genkey (assuan_context_t ctx, char *line)
1353 ctrl_t ctrl = assuan_get_pointer (ctx);
1360 if ( IS_LOCKED (ctrl) )
1361 return gpg_error (GPG_ERR_LOCKED);
1363 force = has_option (line, "--force");
1365 if ((s=has_option_name (line, "--timestamp")))
1368 return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1369 timestamp = isotime2epoch (s+1);
1371 return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1377 line = skip_options (line);
1379 return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1381 while (*line && !spacep (line))
1385 if ((rc = open_card (ctrl, NULL)))
1389 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1391 keyno = xtrystrdup (keyno);
1393 return out_of_core ();
1394 rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
1395 timestamp, pin_cb, ctx);
1398 TEST_CARD_REMOVAL (ctrl, rc);
1403 static const char hlp_random[] =
1406 "Get NBYTES of random from the card and send them back as data.\n"
1407 "This usually involves EEPROM write on the card and thus excessive\n"
1408 "use of this command may destroy the card.\n"
1410 "Note, that this function may be even be used on a locked card.";
1412 cmd_random (assuan_context_t ctx, char *line)
1414 ctrl_t ctrl = assuan_get_pointer (ctx);
1417 unsigned char *buffer;
1420 return set_error (GPG_ERR_ASS_PARAMETER,
1421 "number of requested bytes missing");
1422 nbytes = strtoul (line, NULL, 0);
1424 if ((rc = open_card (ctrl, NULL)))
1428 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1430 buffer = xtrymalloc (nbytes);
1432 return out_of_core ();
1434 rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
1437 rc = assuan_send_data (ctx, buffer, nbytes);
1439 return rc; /* that is already an assuan error code */
1443 TEST_CARD_REMOVAL (ctrl, rc);
1449 static const char hlp_passwd[] =
1450 "PASSWD [--reset] [--nullpin] <chvno>\n"
1452 "Change the PIN or, if --reset is given, reset the retry counter of\n"
1453 "the card holder verification vector CHVNO. The option --nullpin is\n"
1454 "used for TCOS cards to set the initial PIN. The format of CHVNO\n"
1455 "depends on the card application.";
1457 cmd_passwd (assuan_context_t ctx, char *line)
1459 ctrl_t ctrl = assuan_get_pointer (ctx);
1462 unsigned int flags = 0;
1464 if (has_option (line, "--reset"))
1465 flags |= APP_CHANGE_FLAG_RESET;
1466 if (has_option (line, "--nullpin"))
1467 flags |= APP_CHANGE_FLAG_NULLPIN;
1469 if ( IS_LOCKED (ctrl) )
1470 return gpg_error (GPG_ERR_LOCKED);
1472 line = skip_options (line);
1475 return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1477 while (*line && !spacep (line))
1481 if ((rc = open_card (ctrl, NULL)))
1485 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1487 chvnostr = xtrystrdup (chvnostr);
1489 return out_of_core ();
1490 rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
1492 log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1495 TEST_CARD_REMOVAL (ctrl, rc);
1500 static const char hlp_checkpin[] =
1501 "CHECKPIN <idstr>\n"
1503 "Perform a VERIFY operation without doing anything else. This may\n"
1504 "be used to initialize a the PIN cache earlier to long lasting\n"
1505 "operations. Its use is highly application dependent.\n"
1509 " Perform a simple verify operation for CHV1 and CHV2, so that\n"
1510 " further operations won't ask for CHV2 and it is possible to do a\n"
1511 " cheap check on the PIN: If there is something wrong with the PIN\n"
1512 " entry system, only the regular CHV will get blocked and not the\n"
1513 " dangerous CHV3. IDSTR is the usual card's serial number in hex\n"
1514 " notation; an optional fingerprint part will get ignored. There\n"
1515 " is however a special mode if the IDSTR is sffixed with the\n"
1516 " literal string \"[CHV3]\": In this case the Admin PIN is checked\n"
1517 " if and only if the retry counter is still at 3.\n"
1521 " Any of the valid PIN Ids may be used. These are the strings:\n"
1523 " PW1.CH - Global password 1\n"
1524 " PW2.CH - Global password 2\n"
1525 " PW1.CH.SIG - SigG password 1\n"
1526 " PW2.CH.SIG - SigG password 2\n"
1528 " For a definitive list, see the implementation in app-nks.c.\n"
1529 " Note that we call a PW2.* PIN a \"PUK\" despite that since TCOS\n"
1530 " 3.0 they are technically alternative PINs used to mutally\n"
1531 " unblock each other.";
1533 cmd_checkpin (assuan_context_t ctx, char *line)
1535 ctrl_t ctrl = assuan_get_pointer (ctx);
1539 if ( IS_LOCKED (ctrl) )
1540 return gpg_error (GPG_ERR_LOCKED);
1542 if ((rc = open_card (ctrl, NULL)))
1546 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1548 /* We have to use a copy of the key ID because the function may use
1549 the pin_cb which in turn uses the assuan line buffer and thus
1550 overwriting the original line with the keyid. */
1551 idstr = xtrystrdup (line);
1553 return out_of_core ();
1555 rc = app_check_pin (ctrl->app_ctx, idstr, pin_cb, ctx);
1558 log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1560 TEST_CARD_REMOVAL (ctrl, rc);
1565 static const char hlp_lock[] =
1568 "Grant exclusive card access to this session. Note that there is\n"
1569 "no lock counter used and a second lock from the same session will\n"
1570 "be ignored. A single unlock (or RESET) unlocks the session.\n"
1571 "Return GPG_ERR_LOCKED if another session has locked the reader.\n"
1573 "If the option --wait is given the command will wait until a\n"
1574 "lock has been released.";
1576 cmd_lock (assuan_context_t ctx, char *line)
1578 ctrl_t ctrl = assuan_get_pointer (ctx);
1584 if (locked_session != ctrl->server_local)
1585 rc = gpg_error (GPG_ERR_LOCKED);
1588 locked_session = ctrl->server_local;
1591 if (rc && has_option (line, "--wait"))
1594 npth_sleep (1); /* Better implement an event mechanism. However,
1595 for card operations this should be
1597 /* FIXME: Need to check that the connection is still alive.
1598 This can be done by issuing status messages. */
1604 log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1609 static const char hlp_unlock[] =
1612 "Release exclusive card access.";
1614 cmd_unlock (assuan_context_t ctx, char *line)
1616 ctrl_t ctrl = assuan_get_pointer (ctx);
1623 if (locked_session != ctrl->server_local)
1624 rc = gpg_error (GPG_ERR_LOCKED);
1626 locked_session = NULL;
1629 rc = gpg_error (GPG_ERR_NOT_LOCKED);
1632 log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1637 static const char hlp_getinfo[] =
1640 "Multi purpose command to return certain information. \n"
1641 "Supported values of WHAT are:\n"
1643 "version - Return the version of the program.\n"
1644 "pid - Return the process id of the server.\n"
1646 "socket_name - Return the name of the socket.\n"
1648 "status - Return the status of the current reader (in the future, may\n"
1649 "also return the status of all readers). The status is a list of\n"
1650 "one-character flags. The following flags are currently defined:\n"
1651 " 'u' Usable card present. This is the normal state during operation.\n"
1652 " 'r' Card removed. A reset is necessary.\n"
1653 "These flags are exclusive.\n"
1655 "reader_list - Return a list of detected card readers. Does\n"
1656 " currently only work with the internal CCID driver.\n"
1658 "deny_admin - Returns OK if admin commands are not allowed or\n"
1659 " GPG_ERR_GENERAL if admin commands are allowed.\n"
1661 "app_list - Return a list of supported applications. One\n"
1662 " application per line, fields delimited by colons,\n"
1663 " first field is the name.";
1665 cmd_getinfo (assuan_context_t ctx, char *line)
1669 if (!strcmp (line, "version"))
1671 const char *s = VERSION;
1672 rc = assuan_send_data (ctx, s, strlen (s));
1674 else if (!strcmp (line, "pid"))
1678 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1679 rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1681 else if (!strcmp (line, "socket_name"))
1683 const char *s = scd_get_socket_name ();
1686 rc = assuan_send_data (ctx, s, strlen (s));
1688 rc = gpg_error (GPG_ERR_NO_DATA);
1690 else if (!strcmp (line, "status"))
1692 ctrl_t ctrl = assuan_get_pointer (ctx);
1693 int vrdr = ctrl->server_local->vreader_idx;
1696 if (!ctrl->server_local->card_removed && vrdr != -1)
1698 struct vreader_s *vr;
1700 if (!(vrdr >= 0 && vrdr < DIM(vreader_table)))
1703 vr = &vreader_table[vrdr];
1704 if (vr->valid && vr->any && (vr->status & 1))
1707 rc = assuan_send_data (ctx, &flag, 1);
1709 else if (!strcmp (line, "reader_list"))
1712 char *s = ccid_get_reader_list ();
1718 rc = assuan_send_data (ctx, s, strlen (s));
1720 rc = gpg_error (GPG_ERR_NO_DATA);
1723 else if (!strcmp (line, "deny_admin"))
1724 rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1725 else if (!strcmp (line, "app_list"))
1727 char *s = get_supported_applications ();
1729 rc = assuan_send_data (ctx, s, strlen (s));
1735 rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1740 static const char hlp_restart[] =
1743 "Restart the current connection; this is a kind of warm reset. It\n"
1744 "deletes the context used by this connection but does not send a\n"
1745 "RESET to the card. Thus the card itself won't get reset. \n"
1747 "This is used by gpg-agent to reuse a primary pipe connection and\n"
1748 "may be used by clients to backup from a conflict in the serial\n"
1749 "command; i.e. to select another application.";
1751 cmd_restart (assuan_context_t ctx, char *line)
1753 ctrl_t ctrl = assuan_get_pointer (ctx);
1754 struct app_ctx_s *app = ctrl->app_ctx;
1760 ctrl->app_ctx = NULL;
1761 release_application (app);
1763 if (locked_session && ctrl->server_local == locked_session)
1765 locked_session = NULL;
1766 log_info ("implicitly unlocking due to RESTART\n");
1772 static const char hlp_disconnect[] =
1775 "Disconnect the card if it is not any longer used by other\n"
1776 "connections and the backend supports a disconnect operation.";
1778 cmd_disconnect (assuan_context_t ctx, char *line)
1780 ctrl_t ctrl = assuan_get_pointer (ctx);
1784 ctrl->server_local->disconnect_allowed = 1;
1790 static const char hlp_apdu[] =
1791 "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n"
1793 "Send an APDU to the current reader. This command bypasses the high\n"
1794 "level functions and sends the data directly to the card. HEXSTRING\n"
1795 "is expected to be a proper APDU. If HEXSTRING is not given no\n"
1796 "commands are set to the card but the command will implictly check\n"
1797 "whether the card is ready for use. \n"
1799 "Using the option \"--atr\" returns the ATR of the card as a status\n"
1800 "message before any data like this:\n"
1801 " S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1\n"
1803 "Using the option --more handles the card status word MORE_DATA\n"
1804 "(61xx) and concatenates all responses to one block.\n"
1806 "Using the option \"--exlen\" the returned APDU may use extended\n"
1807 "length up to N bytes. If N is not given a default value is used\n"
1808 "(currently 4096).";
1810 cmd_apdu (assuan_context_t ctx, char *line)
1812 ctrl_t ctrl = assuan_get_pointer (ctx);
1814 unsigned char *apdu;
1822 if (has_option (line, "--dump-atr"))
1825 with_atr = has_option (line, "--atr");
1826 handle_more = has_option (line, "--more");
1828 if ((s=has_option_name (line, "--exlen")))
1831 exlen = strtoul (s+1, NULL, 0);
1838 line = skip_options (line);
1840 if ( IS_LOCKED (ctrl) )
1841 return gpg_error (GPG_ERR_LOCKED);
1843 if ((rc = open_card (ctrl, NULL)))
1846 slot = vreader_slot (ctrl->server_local->vreader_idx);
1854 atr = apdu_get_atr (slot, &atrlen);
1855 if (!atr || atrlen > sizeof hexbuf - 2 )
1857 rc = gpg_error (GPG_ERR_INV_CARD);
1862 char *string, *p, *pend;
1864 string = atr_dump (atr, atrlen);
1867 for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1)
1869 rc = assuan_send_data (ctx, p, pend - p + 1);
1871 rc = assuan_send_data (ctx, NULL, 0);
1874 rc = assuan_send_data (ctx, p, strlen (p));
1882 bin2hex (atr, atrlen, hexbuf);
1883 send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1888 apdu = hex_to_buffer (line, &apdulen);
1891 rc = gpg_error_from_syserror ();
1896 unsigned char *result = NULL;
1899 rc = apdu_send_direct (slot, exlen,
1900 apdu, apdulen, handle_more,
1901 &result, &resultlen);
1903 log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1906 rc = assuan_send_data (ctx, result, resultlen);
1913 TEST_CARD_REMOVAL (ctrl, rc);
1918 static const char hlp_killscd[] =
1923 cmd_killscd (assuan_context_t ctx, char *line)
1925 ctrl_t ctrl = assuan_get_pointer (ctx);
1929 ctrl->server_local->stopme = 1;
1930 assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
1936 /* Tell the assuan library about our commands */
1938 register_commands (assuan_context_t ctx)
1942 assuan_handler_t handler;
1943 const char * const help;
1945 { "SERIALNO", cmd_serialno, hlp_serialno },
1946 { "LEARN", cmd_learn, hlp_learn },
1947 { "READCERT", cmd_readcert, hlp_readcert },
1948 { "READKEY", cmd_readkey, hlp_readkey },
1949 { "SETDATA", cmd_setdata, hlp_setdata },
1950 { "PKSIGN", cmd_pksign, hlp_pksign },
1951 { "PKAUTH", cmd_pkauth, hlp_pkauth },
1952 { "PKDECRYPT", cmd_pkdecrypt,hlp_pkdecrypt },
1955 { "GETATTR", cmd_getattr, hlp_getattr },
1956 { "SETATTR", cmd_setattr, hlp_setattr },
1957 { "WRITECERT", cmd_writecert,hlp_writecert },
1958 { "WRITEKEY", cmd_writekey, hlp_writekey },
1959 { "GENKEY", cmd_genkey, hlp_genkey },
1960 { "RANDOM", cmd_random, hlp_random },
1961 { "PASSWD", cmd_passwd, hlp_passwd },
1962 { "CHECKPIN", cmd_checkpin, hlp_checkpin },
1963 { "LOCK", cmd_lock, hlp_lock },
1964 { "UNLOCK", cmd_unlock, hlp_unlock },
1965 { "GETINFO", cmd_getinfo, hlp_getinfo },
1966 { "RESTART", cmd_restart, hlp_restart },
1967 { "DISCONNECT", cmd_disconnect,hlp_disconnect },
1968 { "APDU", cmd_apdu, hlp_apdu },
1969 { "KILLSCD", cmd_killscd, hlp_killscd },
1974 for (i=0; table[i].name; i++)
1976 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
1981 assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1983 assuan_register_reset_notify (ctx, reset_notify);
1984 assuan_register_option_handler (ctx, option_handler);
1989 /* Startup the server. If FD is given as -1 this is simple pipe
1990 server, otherwise it is a regular server. Returns true if there
1991 are no more active asessions. */
1993 scd_command_handler (ctrl_t ctrl, int fd)
1996 assuan_context_t ctx = NULL;
1999 rc = assuan_new (&ctx);
2002 log_error ("failed to allocate assuan context: %s\n",
2009 assuan_fd_t filedes[2];
2011 filedes[0] = assuan_fdopen (0);
2012 filedes[1] = assuan_fdopen (1);
2013 rc = assuan_init_pipe_server (ctx, filedes);
2017 rc = assuan_init_socket_server (ctx, INT2FD(fd),
2018 ASSUAN_SOCKET_SERVER_ACCEPTED);
2022 log_error ("failed to initialize the server: %s\n",
2026 rc = register_commands (ctx);
2029 log_error ("failed to register commands with Assuan: %s\n",
2033 assuan_set_pointer (ctx, ctrl);
2035 /* Allocate and initialize the server object. Put it into the list
2036 of active sessions. */
2037 ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2038 ctrl->server_local->next_session = session_list;
2039 session_list = ctrl->server_local;
2040 ctrl->server_local->ctrl_backlink = ctrl;
2041 ctrl->server_local->assuan_ctx = ctx;
2043 /* We open the reader right at startup so that the ticker is able to
2044 update the status file. */
2045 ctrl->server_local->vreader_idx = get_current_reader ();
2047 /* Command processing loop. */
2050 rc = assuan_accept (ctx);
2057 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2061 rc = assuan_process (ctx);
2064 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2069 /* Cleanup. We don't send an explicit reset to the card. */
2072 /* Release the server object. */
2073 if (session_list == ctrl->server_local)
2074 session_list = ctrl->server_local->next_session;
2077 struct server_local_s *sl;
2079 for (sl=session_list; sl->next_session; sl = sl->next_session)
2080 if (sl->next_session == ctrl->server_local)
2082 if (!sl->next_session)
2084 sl->next_session = ctrl->server_local->next_session;
2086 stopme = ctrl->server_local->stopme;
2087 xfree (ctrl->server_local);
2088 ctrl->server_local = NULL;
2090 /* Release the Assuan context. */
2091 assuan_release (ctx);
2096 /* If there are no more sessions return true. */
2097 return !session_list;
2101 /* Send a line with status information via assuan and escape all given
2102 buffers. The variable elements are pairs of (char *, size_t),
2103 terminated with a (NULL, 0). */
2105 send_status_info (ctrl_t ctrl, const char *keyword, ...)
2108 const unsigned char *value;
2112 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2114 va_start (arg_ptr, keyword);
2118 while ( (value = va_arg (arg_ptr, const unsigned char *)) )
2120 valuelen = va_arg (arg_ptr, size_t);
2122 continue; /* empty buffer */
2128 for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
2130 if (*value < ' ' || *value == '+')
2132 sprintf (p, "%%%02X", *value);
2135 else if (*value == ' ')
2142 assuan_write_status (ctx, keyword, buf);
2148 /* Send a ready formatted status line via assuan. */
2150 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
2152 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2154 if (strchr (args, '\n'))
2155 log_error ("error: LF detected in status line - not sending\n");
2157 assuan_write_status (ctx, keyword, args);
2161 /* Helper to send the clients a status change notification. */
2163 send_client_notifications (void)
2167 #ifdef HAVE_W32_SYSTEM
2175 struct server_local_s *sl;
2177 for (sl=session_list; sl; sl = sl->next_session)
2179 if (sl->event_signal && sl->assuan_ctx)
2181 pid_t pid = assuan_get_pid (sl->assuan_ctx);
2182 #ifdef HAVE_W32_SYSTEM
2183 HANDLE handle = (void *)sl->event_signal;
2185 for (kidx=0; kidx < killidx; kidx++)
2186 if (killed[kidx].pid == pid
2187 && killed[kidx].handle == handle)
2190 log_info ("event %lx (%p) already triggered for client %d\n",
2191 sl->event_signal, handle, (int)pid);
2194 log_info ("triggering event %lx (%p) for client %d\n",
2195 sl->event_signal, handle, (int)pid);
2196 if (!SetEvent (handle))
2197 log_error ("SetEvent(%lx) failed: %s\n",
2198 sl->event_signal, w32_strerror (-1));
2199 if (killidx < DIM (killed))
2201 killed[killidx].pid = pid;
2202 killed[killidx].handle = handle;
2206 #else /*!HAVE_W32_SYSTEM*/
2207 int signo = sl->event_signal;
2209 if (pid != (pid_t)(-1) && pid && signo > 0)
2211 for (kidx=0; kidx < killidx; kidx++)
2212 if (killed[kidx].pid == pid
2213 && killed[kidx].signo == signo)
2216 log_info ("signal %d already sent to client %d\n",
2220 log_info ("sending signal %d to client %d\n",
2223 if (killidx < DIM (killed))
2225 killed[killidx].pid = pid;
2226 killed[killidx].signo = signo;
2231 #endif /*!HAVE_W32_SYSTEM*/
2238 /* This is the core of scd_update_reader_status_file but the caller
2239 needs to take care of the locking. */
2241 update_reader_status_file (int set_card_removed_flag)
2244 unsigned int status, changed;
2246 /* Note, that we only try to get the status, because it does not
2247 make sense to wait here for a operation to complete. If we are
2248 busy working with a card, delays in the status file update should
2250 for (idx=0; idx < DIM(vreader_table); idx++)
2252 struct vreader_s *vr = vreader_table + idx;
2253 struct server_local_s *sl;
2256 if (!vr->valid || vr->slot == -1)
2257 continue; /* Not valid or reader not yet open. */
2259 sw_apdu = apdu_get_status (vr->slot, 0, &status, &changed);
2260 if (sw_apdu == SW_HOST_NO_READER)
2262 /* Most likely the _reader_ has been unplugged. */
2263 apdu_close_reader (vr->slot);
2265 changed = vr->changed;
2269 /* Get status failed. Ignore that. */
2273 if (!vr->any || vr->status != status || vr->changed != changed )
2279 log_info ("updating reader %d (%d) status: 0x%04X->0x%04X (%u->%u)\n",
2280 idx, vr->slot, vr->status, status, vr->changed, changed);
2281 vr->status = status;
2282 vr->changed = changed;
2284 /* FIXME: Should this be IDX instead of vr->slot? This
2285 depends on how client sessions will associate the reader
2286 status with their session. */
2287 snprintf (templ, sizeof templ, "reader_%d.status", vr->slot);
2288 fname = make_filename (gnupg_homedir (), templ, NULL );
2289 fp = fopen (fname, "w");
2292 fprintf (fp, "%s\n",
2293 (status & 1)? "USABLE":
2294 (status & 4)? "ACTIVE":
2295 (status & 2)? "PRESENT": "NOCARD");
2300 /* If a status script is executable, run it. */
2302 const char *args[9], *envs[2];
2303 char numbuf1[30], numbuf2[30], numbuf3[30];
2304 char *homestr, *envstr;
2307 homestr = make_filename (gnupg_homedir (), NULL);
2308 if (gpgrt_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
2309 log_error ("out of core while building environment\n");
2315 sprintf (numbuf1, "%d", vr->slot);
2316 sprintf (numbuf2, "0x%04X", vr->status);
2317 sprintf (numbuf3, "0x%04X", status);
2318 args[0] = "--reader-port";
2320 args[2] = "--old-code";
2322 args[4] = "--new-code";
2324 args[6] = "--status";
2325 args[7] = ((status & 1)? "USABLE":
2326 (status & 4)? "ACTIVE":
2327 (status & 2)? "PRESENT": "NOCARD");
2330 fname = make_filename (gnupg_homedir (), "scd-event", NULL);
2331 err = gnupg_spawn_process_detached (fname, args, envs);
2332 if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
2333 log_error ("failed to run event handler '%s': %s\n",
2334 fname, gpg_strerror (err));
2341 /* Set the card removed flag for all current sessions. */
2342 if (vr->any && vr->status == 0 && set_card_removed_flag)
2343 update_card_removed (idx, 1);
2347 /* Send a signal to all clients who applied for it. */
2348 send_client_notifications ();
2351 /* Check whether a disconnect is pending. */
2352 if (opt.card_timeout)
2354 for (sl=session_list; sl; sl = sl->next_session)
2355 if (!sl->disconnect_allowed)
2357 if (session_list && !sl)
2359 /* FIXME: Use a real timeout. */
2360 /* At least one connection and all allow a disconnect. */
2361 log_info ("disconnecting card in reader %d (%d)\n",
2363 apdu_disconnect (vr->slot);
2370 /* This function is called by the ticker thread to check for changes
2371 of the reader stati. It updates the reader status files and if
2372 requested by the caller also send a signal to the caller. */
2374 scd_update_reader_status_file (void)
2377 err = npth_mutex_lock (&status_file_update_lock);
2379 return; /* locked - give up. */
2380 update_reader_status_file (1);
2381 err = npth_mutex_unlock (&status_file_update_lock);
2383 log_error ("failed to release status_file_update lock: %s\n",