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 /* Flag indicating that the application context needs to be released
133 at the next opportunity. */
134 int app_ctx_marked_for_release;
136 /* A disconnect command has been sent. */
137 int disconnect_allowed;
139 /* If set to true we will be terminate ourself at the end of the
146 /* The table with information on all used virtual readers. */
147 static struct vreader_s vreader_table[10];
150 /* To keep track of all running sessions, we link all active server
151 contexts and the anchor in this variable. */
152 static struct server_local_s *session_list;
154 /* If a session has been locked we store a link to its server object
156 static struct server_local_s *locked_session;
158 /* While doing a reset we need to make sure that the ticker does not
159 call scd_update_reader_status_file while we are using it. */
160 static npth_mutex_t status_file_update_lock;
163 /*-- Local prototypes --*/
164 static void update_reader_status_file (int set_card_removed_flag);
169 /* This function must be called once to initialize this module. This
170 has to be done before a second thread is spawned. We can't do the
171 static initialization because Pth emulation code might not be able
172 to do a static init; in particular, it is not possible for W32. */
174 initialize_module_command (void)
176 static int initialized;
181 err = npth_mutex_init (&status_file_update_lock, NULL);
188 /* Helper to return the slot number for a given virtual reader index
189 VRDR. In case on an error -1 is returned. */
191 vreader_slot (int vrdr)
193 if (vrdr == -1 || !(vrdr >= 0 && vrdr < DIM(vreader_table)))
195 if (!vreader_table [vrdr].valid)
197 return vreader_table[vrdr].slot;
201 /* Update the CARD_REMOVED element of all sessions using the virtual
202 reader given by VRDR to VALUE. */
204 update_card_removed (int vrdr, int value)
206 struct server_local_s *sl;
211 for (sl=session_list; sl; sl = sl->next_session)
212 if (sl->ctrl_backlink
213 && sl->ctrl_backlink->server_local->vreader_idx == vrdr)
215 sl->card_removed = value;
217 /* Let the card application layer know about the removal. */
219 application_notify_card_reset (vreader_slot (vrdr));
223 /* Convert the STRING into a newly allocated buffer while translating
224 the hex numbers. Stops at the first invalid character. Blanks and
225 colons are allowed to separate the hex digits. Returns NULL on
226 error or a newly malloced buffer and its length in LENGTH. */
227 static unsigned char *
228 hex_to_buffer (const char *string, size_t *r_length)
230 unsigned char *buffer;
234 buffer = xtrymalloc (strlen (string)+1);
237 for (s=string, n=0; *s; s++)
239 if (spacep (s) || *s == ':')
241 if (hexdigitp (s) && hexdigitp (s+1))
243 buffer[n++] = xtoi_2 (s);
255 /* Reset the card and free the application context. With SEND_RESET
256 set to true actually send a RESET to the reader; this is the normal
257 way of calling the function. */
259 do_reset (ctrl_t ctrl, int send_reset)
261 int vrdr = ctrl->server_local->vreader_idx;
265 if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table))))
268 /* If there is an active application, release it. Tell all other
269 sessions using the same application to release the
273 release_application (ctrl->app_ctx);
274 ctrl->app_ctx = NULL;
277 struct server_local_s *sl;
279 for (sl=session_list; sl; sl = sl->next_session)
280 if (sl->ctrl_backlink
281 && sl->ctrl_backlink->server_local->vreader_idx == vrdr)
283 sl->app_ctx_marked_for_release = 1;
288 /* If we want a real reset for the card, send the reset APDU and
289 tell the application layer about it. */
290 slot = vreader_slot (vrdr);
291 if (slot != -1 && send_reset && !IS_LOCKED (ctrl) )
293 application_notify_card_reset (slot);
294 switch (apdu_reset (slot))
298 case SW_HOST_NO_CARD:
299 case SW_HOST_CARD_INACTIVE:
302 apdu_close_reader (slot);
303 vreader_table[vrdr].slot = slot = -1;
308 /* If we hold a lock, unlock now. */
309 if (locked_session && ctrl->server_local == locked_session)
311 locked_session = NULL;
312 log_info ("implicitly unlocking due to RESET\n");
315 /* Reset the card removed flag for the current reader. We need to
316 take the lock here so that the ticker thread won't concurrently
317 try to update the file. Calling update_reader_status_file is
318 required to get hold of the new status of the card in the vreader
320 err = npth_mutex_lock (&status_file_update_lock);
323 log_error ("failed to acquire status_file_update lock\n");
324 ctrl->server_local->vreader_idx = -1;
327 update_reader_status_file (0); /* Update slot status table. */
328 update_card_removed (vrdr, 0); /* Clear card_removed flag. */
329 err = npth_mutex_unlock (&status_file_update_lock);
331 log_error ("failed to release status_file_update lock: %s\n",
334 /* Do this last, so that the update_card_removed above does its job. */
335 ctrl->server_local->vreader_idx = -1;
340 reset_notify (assuan_context_t ctx, char *line)
342 ctrl_t ctrl = assuan_get_pointer (ctx);
352 option_handler (assuan_context_t ctx, const char *key, const char *value)
354 ctrl_t ctrl = assuan_get_pointer (ctx);
356 if (!strcmp (key, "event-signal"))
358 /* A value of 0 is allowed to reset the event signal. */
359 #ifdef HAVE_W32_SYSTEM
361 return gpg_error (GPG_ERR_ASS_PARAMETER);
362 ctrl->server_local->event_signal = strtoul (value, NULL, 16);
364 int i = *value? atoi (value) : -1;
366 return gpg_error (GPG_ERR_ASS_PARAMETER);
367 ctrl->server_local->event_signal = i;
375 /* Return the index of the current reader or open the reader if no
376 other sessions are using that reader. If it is not possible to
377 open the reader -1 is returned. Note, that we currently support
378 only one reader but most of the code (except for this function)
379 should be able to cope with several readers. */
381 get_current_reader (void)
383 struct vreader_s *vr;
385 /* We only support one reader for now. */
386 vr = &vreader_table[0];
388 /* Initialize the vreader item if not yet done. */
395 /* Try to open the reader. */
398 vr->slot = apdu_open_reader (opt.reader_port);
400 /* If we still don't have a slot, we have no readers.
401 Invalidate for now until a reader is attached. */
408 /* Return the vreader index or -1. */
409 return vr->valid ? 0 : -1;
413 /* If the card has not yet been opened, do it. */
415 open_card (ctrl_t ctrl, const char *apptype)
420 /* If we ever got a card not present error code, return that. Only
421 the SERIALNO command and a reset are able to clear from that
423 if (ctrl->server_local->card_removed)
424 return gpg_error (GPG_ERR_CARD_REMOVED);
426 if ( IS_LOCKED (ctrl) )
427 return gpg_error (GPG_ERR_LOCKED);
429 /* If the application has been marked for release do it now. We
430 can't do it immediately in do_reset because the application may
432 if (ctrl->server_local->app_ctx_marked_for_release)
434 ctrl->server_local->app_ctx_marked_for_release = 0;
435 release_application (ctrl->app_ctx);
436 ctrl->app_ctx = NULL;
439 /* If we are already initialized for one specific application we
440 need to check that the client didn't requested a specific
441 application different from the one in use before we continue. */
444 return check_application_conflict
445 (ctrl, vreader_slot (ctrl->server_local->vreader_idx), apptype);
448 /* Setup the vreader and select the application. */
449 if (ctrl->server_local->vreader_idx != -1)
450 vrdr = ctrl->server_local->vreader_idx;
452 vrdr = get_current_reader ();
453 ctrl->server_local->vreader_idx = vrdr;
455 err = gpg_error (GPG_ERR_CARD);
458 /* Fixme: We should move the apdu_connect call to
459 select_application. */
461 int slot = vreader_slot (vrdr);
463 ctrl->server_local->disconnect_allowed = 0;
464 sw = apdu_connect (slot);
465 if (sw && sw != SW_HOST_ALREADY_CONNECTED)
467 if (sw == SW_HOST_NO_CARD)
468 err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
469 else if (sw == SW_HOST_CARD_INACTIVE)
470 err = gpg_error (GPG_ERR_CARD_RESET);
472 err = gpg_error (GPG_ERR_ENODEV);
475 err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
478 TEST_CARD_REMOVAL (ctrl, err);
483 static const char hlp_serialno[] =
484 "SERIALNO [<apptype>]\n"
486 "Return the serial number of the card using a status response. This\n"
487 "function should be used to check for the presence of a card.\n"
489 "If APPTYPE is given, an application of that type is selected and an\n"
490 "error is returned if the application is not supported or available.\n"
491 "The default is to auto-select the application using a hardwired\n"
492 "preference system. Note, that a future extension to this function\n"
493 "may allow to specify a list and order of applications to try.\n"
495 "This function is special in that it can be used to reset the card.\n"
496 "Most other functions will return an error when a card change has\n"
497 "been detected and the use of this function is therefore required.\n"
499 "Background: We want to keep the client clear of handling card\n"
500 "changes between operations; i.e. the client can assume that all\n"
501 "operations are done on the same card unless he calls this function.";
503 cmd_serialno (assuan_context_t ctx, char *line)
505 ctrl_t ctrl = assuan_get_pointer (ctx);
511 /* Clear the remove flag so that the open_card is able to reread it. */
513 if (ctrl->server_local->card_removed)
515 if ( IS_LOCKED (ctrl) )
516 return gpg_error (GPG_ERR_LOCKED);
520 if ((rc = open_card (ctrl, *line? line:NULL)))
522 /* In case of an inactive card, retry once. */
523 if (gpg_err_code (rc) == GPG_ERR_CARD_RESET && retries++ < 1)
528 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
532 rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
533 serial, (unsigned long)stamp);
539 static const char hlp_learn[] =
540 "LEARN [--force] [--keypairinfo]\n"
542 "Learn all useful information of the currently inserted card. When\n"
543 "used without the force options, the command might do an INQUIRE\n"
546 " INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>\n"
548 "The client should just send an \"END\" if the processing should go on\n"
549 "or a \"CANCEL\" to force the function to terminate with a Cancel\n"
552 "With the option --keypairinfo only KEYPARIINFO lstatus lines are\n"
555 "The response of this command is a list of status lines formatted as\n"
558 " S APPTYPE <apptype>\n"
560 "This returns the type of the application, currently the strings:\n"
562 " P15 = PKCS-15 structure used\n"
563 " DINSIG = DIN SIG\n"
564 " OPENPGP = OpenPGP card\n"
565 " NKS = NetKey card\n"
567 "are implemented. These strings are aliases for the AID\n"
569 " S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>\n"
571 "If there is no certificate yet stored on the card a single 'X' is\n"
572 "returned as the keygrip. In addition to the keypair info, information\n"
573 "about all certificates stored on the card is also returned:\n"
575 " S CERTINFO <certtype> <hexstring_with_id>\n"
577 "Where CERTTYPE is a number indicating the type of certificate:\n"
579 " 100 := Regular X.509 cert\n"
580 " 101 := Trusted X.509 cert\n"
581 " 102 := Useful X.509 cert\n"
582 " 110 := Root CA cert in a special format (e.g. DINSIG)\n"
583 " 111 := Root CA cert as standard X509 cert.\n"
585 "For certain cards, more information will be returned:\n"
587 " S KEY-FPR <no> <hexstring>\n"
589 "For OpenPGP cards this returns the stored fingerprints of the\n"
590 "keys. This can be used check whether a key is available on the\n"
591 "card. NO may be 1, 2 or 3.\n"
593 " S CA-FPR <no> <hexstring>\n"
595 "Similar to above, these are the fingerprints of keys assumed to be\n"
596 "ultimately trusted.\n"
598 " S DISP-NAME <name_of_card_holder>\n"
600 "The name of the card holder as stored on the card; percent\n"
601 "escaping takes place, spaces are encoded as '+'\n"
603 " S PUBKEY-URL <url>\n"
605 "The URL to be used for locating the entire public key.\n"
607 "Note, that this function may even be used on a locked card.";
609 cmd_learn (assuan_context_t ctx, char *line)
611 ctrl_t ctrl = assuan_get_pointer (ctx);
613 int only_keypairinfo = has_option (line, "--keypairinfo");
615 if ((rc = open_card (ctrl, NULL)))
618 /* Unless the force option is used we try a shortcut by identifying
619 the card using a serial number and inquiring the client with
620 that. The client may choose to cancel the operation if he already
621 knows about this card */
622 if (!only_keypairinfo)
629 slot = vreader_slot (ctrl->server_local->vreader_idx);
630 reader = apdu_get_reader_name (slot);
632 return out_of_core ();
633 send_status_direct (ctrl, "READER", reader);
634 /* No need to free the string of READER. */
636 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
640 rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
641 serial, (unsigned long)stamp);
645 return out_of_core ();
648 if (!has_option (line, "--force"))
652 rc = gpgrt_asprintf (&command, "KNOWNCARDP %s %lu",
653 serial, (unsigned long)stamp);
657 return out_of_core ();
659 rc = assuan_inquire (ctx, command, NULL, NULL, 0);
663 if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
664 log_error ("inquire KNOWNCARDP failed: %s\n",
669 /* Not canceled, so we have to proceeed. */
674 /* Let the application print out its collection of useful status
677 rc = app_write_learn_status (ctrl->app_ctx, ctrl, only_keypairinfo);
679 TEST_CARD_REMOVAL (ctrl, rc);
685 static const char hlp_readcert[] =
686 "READCERT <hexified_certid>|<keyid>\n"
688 "Note, that this function may even be used on a locked card.";
690 cmd_readcert (assuan_context_t ctx, char *line)
692 ctrl_t ctrl = assuan_get_pointer (ctx);
697 if ((rc = open_card (ctrl, NULL)))
700 line = xstrdup (line); /* Need a copy of the line. */
701 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
703 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
708 rc = assuan_send_data (ctx, cert, ncert);
714 TEST_CARD_REMOVAL (ctrl, rc);
719 static const char hlp_readkey[] =
722 "Return the public key for the given cert or key ID as a standard\n"
725 "Note, that this function may even be used on a locked card.";
727 cmd_readkey (assuan_context_t ctx, char *line)
729 ctrl_t ctrl = assuan_get_pointer (ctx);
731 unsigned char *cert = NULL;
733 ksba_cert_t kc = NULL;
738 if ((rc = open_card (ctrl, NULL)))
741 line = xstrdup (line); /* Need a copy of the line. */
742 /* If the application supports the READKEY function we use that.
743 Otherwise we use the old way by extracting it from the
745 rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen);
747 { /* Yeah, got that key - send it back. */
748 rc = assuan_send_data (ctx, pk, pklen);
755 if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
756 log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
759 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
761 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
768 rc = ksba_cert_new (&kc);
772 rc = ksba_cert_init_from_mem (kc, cert, ncert);
775 log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
779 p = ksba_cert_get_public_key (kc);
782 rc = gpg_error (GPG_ERR_NO_PUBKEY);
786 n = gcry_sexp_canon_len (p, 0, NULL, NULL);
787 rc = assuan_send_data (ctx, p, n);
792 ksba_cert_release (kc);
794 TEST_CARD_REMOVAL (ctrl, rc);
800 static const char hlp_setdata[] =
801 "SETDATA [--append] <hexstring>\n"
803 "The client should use this command to tell us the data he want to sign.\n"
804 "With the option --append, the data is appended to the data set by a\n"
805 "previous SETDATA command.";
807 cmd_setdata (assuan_context_t ctx, char *line)
809 ctrl_t ctrl = assuan_get_pointer (ctx);
815 append = (ctrl->in_data.value && has_option (line, "--append"));
817 line = skip_options (line);
819 if (locked_session && locked_session != ctrl->server_local)
820 return gpg_error (GPG_ERR_LOCKED);
822 /* Parse the hexstring. */
823 for (p=line,n=0; hexdigitp (p); p++, n++)
826 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
828 return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
830 return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
834 if (ctrl->in_data.valuelen + n > MAXLEN_SETDATA)
835 return set_error (GPG_ERR_TOO_LARGE,
836 "limit on total size of data reached");
837 buf = xtrymalloc (ctrl->in_data.valuelen + n);
840 buf = xtrymalloc (n);
842 return out_of_core ();
846 memcpy (buf, ctrl->in_data.value, ctrl->in_data.valuelen);
847 off = ctrl->in_data.valuelen;
851 for (p=line, i=0; i < n; p += 2, i++)
852 buf[off+i] = xtoi_2 (p);
854 xfree (ctrl->in_data.value);
855 ctrl->in_data.value = buf;
856 ctrl->in_data.valuelen = off+n;
863 pin_cb (void *opaque, const char *info, char **retstr)
865 assuan_context_t ctx = opaque;
868 unsigned char *value;
873 /* We prompt for pinpad entry. To make sure that the popup has
874 been show we use an inquire and not just a status message.
875 We ignore any value returned. */
878 log_debug ("prompting for pinpad entry '%s'\n", info);
879 rc = gpgrt_asprintf (&command, "POPUPPINPADPROMPT %s", info);
881 return gpg_error (gpg_err_code_from_errno (errno));
882 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
887 log_debug ("dismiss pinpad entry prompt\n");
888 rc = assuan_inquire (ctx, "DISMISSPINPADPROMPT",
889 &value, &valuelen, MAXLEN_PIN);
897 log_debug ("asking for PIN '%s'\n", info);
899 rc = gpgrt_asprintf (&command, "NEEDPIN %s", info);
901 return gpg_error (gpg_err_code_from_errno (errno));
903 /* Fixme: Write an inquire function which returns the result in
904 secure memory and check all further handling of the PIN. */
905 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
910 if (!valuelen || value[valuelen-1])
912 /* We require that the returned value is an UTF-8 string */
914 return gpg_error (GPG_ERR_INV_RESPONSE);
916 *retstr = (char*)value;
921 static const char hlp_pksign[] =
922 "PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5]] <hexified_id>\n"
924 "The --hash option is optional; the default is SHA1.";
926 cmd_pksign (assuan_context_t ctx, char *line)
928 ctrl_t ctrl = assuan_get_pointer (ctx);
930 unsigned char *outdata;
935 if (has_option (line, "--hash=rmd160"))
936 hash_algo = GCRY_MD_RMD160;
937 else if (has_option (line, "--hash=sha1"))
938 hash_algo = GCRY_MD_SHA1;
939 else if (has_option (line, "--hash=sha224"))
940 hash_algo = GCRY_MD_SHA224;
941 else if (has_option (line, "--hash=sha256"))
942 hash_algo = GCRY_MD_SHA256;
943 else if (has_option (line, "--hash=sha384"))
944 hash_algo = GCRY_MD_SHA384;
945 else if (has_option (line, "--hash=sha512"))
946 hash_algo = GCRY_MD_SHA512;
947 else if (has_option (line, "--hash=md5"))
948 hash_algo = GCRY_MD_MD5;
949 else if (!strstr (line, "--"))
950 hash_algo = GCRY_MD_SHA1;
952 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
954 line = skip_options (line);
956 if ( IS_LOCKED (ctrl) )
957 return gpg_error (GPG_ERR_LOCKED);
959 if ((rc = open_card (ctrl, NULL)))
962 /* We have to use a copy of the key ID because the function may use
963 the pin_cb which in turn uses the assuan line buffer and thus
964 overwriting the original line with the keyid */
965 keyidstr = xtrystrdup (line);
967 return out_of_core ();
969 rc = app_sign (ctrl->app_ctx,
972 ctrl->in_data.value, ctrl->in_data.valuelen,
973 &outdata, &outdatalen);
978 log_error ("app_sign failed: %s\n", gpg_strerror (rc));
982 rc = assuan_send_data (ctx, outdata, outdatalen);
985 return rc; /* that is already an assuan error code */
988 TEST_CARD_REMOVAL (ctrl, rc);
993 static const char hlp_pkauth[] =
994 "PKAUTH <hexified_id>";
996 cmd_pkauth (assuan_context_t ctx, char *line)
998 ctrl_t ctrl = assuan_get_pointer (ctx);
1000 unsigned char *outdata;
1004 if ( IS_LOCKED (ctrl) )
1005 return gpg_error (GPG_ERR_LOCKED);
1007 if ((rc = open_card (ctrl, NULL)))
1011 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1013 /* We have to use a copy of the key ID because the function may use
1014 the pin_cb which in turn uses the assuan line buffer and thus
1015 overwriting the original line with the keyid */
1016 keyidstr = xtrystrdup (line);
1018 return out_of_core ();
1020 rc = app_auth (ctrl->app_ctx,
1023 ctrl->in_data.value, ctrl->in_data.valuelen,
1024 &outdata, &outdatalen);
1028 log_error ("app_auth failed: %s\n", gpg_strerror (rc));
1032 rc = assuan_send_data (ctx, outdata, outdatalen);
1035 return rc; /* that is already an assuan error code */
1038 TEST_CARD_REMOVAL (ctrl, rc);
1043 static const char hlp_pkdecrypt[] =
1044 "PKDECRYPT <hexified_id>";
1046 cmd_pkdecrypt (assuan_context_t ctx, char *line)
1048 ctrl_t ctrl = assuan_get_pointer (ctx);
1050 unsigned char *outdata;
1053 unsigned int infoflags;
1055 if ( IS_LOCKED (ctrl) )
1056 return gpg_error (GPG_ERR_LOCKED);
1058 if ((rc = open_card (ctrl, NULL)))
1061 keyidstr = xtrystrdup (line);
1063 return out_of_core ();
1064 rc = app_decipher (ctrl->app_ctx,
1067 ctrl->in_data.value, ctrl->in_data.valuelen,
1068 &outdata, &outdatalen, &infoflags);
1073 log_error ("app_decipher failed: %s\n", gpg_strerror (rc));
1077 /* If the card driver told us that there is no padding, send a
1078 status line. If there is a padding it is assumed that the
1079 caller knows what padding is used. It would have been better
1080 to always send that information but for backward
1081 compatibility we can't do that. */
1082 if ((infoflags & APP_DECIPHER_INFO_NOPAD))
1083 send_status_direct (ctrl, "PADDING", "0");
1084 rc = assuan_send_data (ctx, outdata, outdatalen);
1087 return rc; /* that is already an assuan error code */
1090 TEST_CARD_REMOVAL (ctrl, rc);
1095 static const char hlp_getattr[] =
1098 "This command is used to retrieve data from a smartcard. The\n"
1099 "allowed names depend on the currently selected smartcard\n"
1100 "application. NAME must be percent and '+' escaped. The value is\n"
1101 "returned through status message, see the LEARN command for details.\n"
1103 "However, the current implementation assumes that Name is not escaped;\n"
1104 "this works as long as no one uses arbitrary escaping. \n"
1106 "Note, that this function may even be used on a locked card.";
1108 cmd_getattr (assuan_context_t ctx, char *line)
1110 ctrl_t ctrl = assuan_get_pointer (ctx);
1112 const char *keyword;
1114 if ((rc = open_card (ctrl, NULL)))
1118 for (; *line && !spacep (line); line++)
1123 /* (We ignore any garbage for now.) */
1125 /* FIXME: Applications should not return sensitive data if the card
1127 rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
1129 TEST_CARD_REMOVAL (ctrl, rc);
1134 static const char hlp_setattr[] =
1135 "SETATTR <name> <value> \n"
1137 "This command is used to store data on a a smartcard. The allowed\n"
1138 "names and values are depend on the currently selected smartcard\n"
1139 "application. NAME and VALUE must be percent and '+' escaped.\n"
1141 "However, the current implementation assumes that NAME is not\n"
1142 "escaped; this works as long as no one uses arbitrary escaping.\n"
1144 "A PIN will be requested for most NAMEs. See the corresponding\n"
1145 "setattr function of the actually used application (app-*.c) for\n"
1148 cmd_setattr (assuan_context_t ctx, char *orig_line)
1150 ctrl_t ctrl = assuan_get_pointer (ctx);
1155 char *line, *linebuf;
1157 if ( IS_LOCKED (ctrl) )
1158 return gpg_error (GPG_ERR_LOCKED);
1160 if ((rc = open_card (ctrl, NULL)))
1163 /* We need to use a copy of LINE, because PIN_CB uses the same
1164 context and thus reuses the Assuan provided LINE. */
1165 line = linebuf = xtrystrdup (orig_line);
1167 return out_of_core ();
1170 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1174 while (spacep (line))
1176 nbytes = percent_plus_unescape_inplace (line, 0);
1178 rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx,
1179 (const unsigned char*)line, nbytes);
1182 TEST_CARD_REMOVAL (ctrl, rc);
1187 static const char hlp_writecert[] =
1188 "WRITECERT <hexified_certid>\n"
1190 "This command is used to store a certifciate on a smartcard. The\n"
1191 "allowed certids depend on the currently selected smartcard\n"
1192 "application. The actual certifciate is requested using the inquiry\n"
1193 "\"CERTDATA\" and needs to be provided in its raw (e.g. DER) form.\n"
1195 "In almost all cases a a PIN will be requested. See the related\n"
1196 "writecert function of the actually used application (app-*.c) for\n"
1199 cmd_writecert (assuan_context_t ctx, char *line)
1201 ctrl_t ctrl = assuan_get_pointer (ctx);
1204 unsigned char *certdata;
1207 if ( IS_LOCKED (ctrl) )
1208 return gpg_error (GPG_ERR_LOCKED);
1210 line = skip_options (line);
1213 return set_error (GPG_ERR_ASS_PARAMETER, "no certid given");
1215 while (*line && !spacep (line))
1219 if ((rc = open_card (ctrl, NULL)))
1223 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1225 certid = xtrystrdup (certid);
1227 return out_of_core ();
1229 /* Now get the actual keydata. */
1230 rc = assuan_inquire (ctx, "CERTDATA",
1231 &certdata, &certdatalen, MAXLEN_CERTDATA);
1238 /* Write the certificate to the card. */
1239 rc = app_writecert (ctrl->app_ctx, ctrl, certid,
1240 pin_cb, ctx, certdata, certdatalen);
1244 TEST_CARD_REMOVAL (ctrl, rc);
1249 static const char hlp_writekey[] =
1250 "WRITEKEY [--force] <keyid> \n"
1252 "This command is used to store a secret key on a a smartcard. The\n"
1253 "allowed keyids depend on the currently selected smartcard\n"
1254 "application. The actual keydata is requested using the inquiry\n"
1255 "\"KEYDATA\" and need to be provided without any protection. With\n"
1256 "--force set an existing key under this KEYID will get overwritten.\n"
1257 "The keydata is expected to be the usual canonical encoded\n"
1260 "A PIN will be requested for most NAMEs. See the corresponding\n"
1261 "writekey function of the actually used application (app-*.c) for\n"
1264 cmd_writekey (assuan_context_t ctx, char *line)
1266 ctrl_t ctrl = assuan_get_pointer (ctx);
1269 int force = has_option (line, "--force");
1270 unsigned char *keydata;
1273 if ( IS_LOCKED (ctrl) )
1274 return gpg_error (GPG_ERR_LOCKED);
1276 line = skip_options (line);
1279 return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1281 while (*line && !spacep (line))
1285 if ((rc = open_card (ctrl, NULL)))
1289 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1291 keyid = xtrystrdup (keyid);
1293 return out_of_core ();
1295 /* Now get the actual keydata. */
1296 assuan_begin_confidential (ctx);
1297 rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1298 assuan_end_confidential (ctx);
1305 /* Write the key to the card. */
1306 rc = app_writekey (ctrl->app_ctx, ctrl, keyid, force? 1:0,
1307 pin_cb, ctx, keydata, keydatalen);
1311 TEST_CARD_REMOVAL (ctrl, rc);
1316 static const char hlp_genkey[] =
1317 "GENKEY [--force] [--timestamp=<isodate>] <no>\n"
1319 "Generate a key on-card identified by NO, which is application\n"
1320 "specific. Return values are application specific. For OpenPGP\n"
1321 "cards 3 status lines are returned:\n"
1323 " S KEY-FPR <hexstring>\n"
1324 " S KEY-CREATED-AT <seconds_since_epoch>\n"
1325 " S KEY-DATA [-|p|n] <hexdata>\n"
1327 " 'p' and 'n' are the names of the RSA parameters; '-' is used to\n"
1328 " indicate that HEXDATA is the first chunk of a parameter given\n"
1329 " by the next KEY-DATA.\n"
1331 "--force is required to overwrite an already existing key. The\n"
1332 "KEY-CREATED-AT is required for further processing because it is\n"
1333 "part of the hashed key material for the fingerprint.\n"
1335 "If --timestamp is given an OpenPGP key will be created using this\n"
1336 "value. The value needs to be in ISO Format; e.g.\n"
1337 "\"--timestamp=20030316T120000\" and after 1970-01-01 00:00:00.\n"
1339 "The public part of the key can also later be retrieved using the\n"
1342 cmd_genkey (assuan_context_t ctx, char *line)
1344 ctrl_t ctrl = assuan_get_pointer (ctx);
1351 if ( IS_LOCKED (ctrl) )
1352 return gpg_error (GPG_ERR_LOCKED);
1354 force = has_option (line, "--force");
1356 if ((s=has_option_name (line, "--timestamp")))
1359 return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1360 timestamp = isotime2epoch (s+1);
1362 return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1368 line = skip_options (line);
1370 return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1372 while (*line && !spacep (line))
1376 if ((rc = open_card (ctrl, NULL)))
1380 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1382 keyno = xtrystrdup (keyno);
1384 return out_of_core ();
1385 rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
1386 timestamp, pin_cb, ctx);
1389 TEST_CARD_REMOVAL (ctrl, rc);
1394 static const char hlp_random[] =
1397 "Get NBYTES of random from the card and send them back as data.\n"
1398 "This usually involves EEPROM write on the card and thus excessive\n"
1399 "use of this command may destroy the card.\n"
1401 "Note, that this function may be even be used on a locked card.";
1403 cmd_random (assuan_context_t ctx, char *line)
1405 ctrl_t ctrl = assuan_get_pointer (ctx);
1408 unsigned char *buffer;
1411 return set_error (GPG_ERR_ASS_PARAMETER,
1412 "number of requested bytes missing");
1413 nbytes = strtoul (line, NULL, 0);
1415 if ((rc = open_card (ctrl, NULL)))
1419 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1421 buffer = xtrymalloc (nbytes);
1423 return out_of_core ();
1425 rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
1428 rc = assuan_send_data (ctx, buffer, nbytes);
1430 return rc; /* that is already an assuan error code */
1434 TEST_CARD_REMOVAL (ctrl, rc);
1440 static const char hlp_passwd[] =
1441 "PASSWD [--reset] [--nullpin] <chvno>\n"
1443 "Change the PIN or, if --reset is given, reset the retry counter of\n"
1444 "the card holder verification vector CHVNO. The option --nullpin is\n"
1445 "used for TCOS cards to set the initial PIN. The format of CHVNO\n"
1446 "depends on the card application.";
1448 cmd_passwd (assuan_context_t ctx, char *line)
1450 ctrl_t ctrl = assuan_get_pointer (ctx);
1453 unsigned int flags = 0;
1455 if (has_option (line, "--reset"))
1456 flags |= APP_CHANGE_FLAG_RESET;
1457 if (has_option (line, "--nullpin"))
1458 flags |= APP_CHANGE_FLAG_NULLPIN;
1460 if ( IS_LOCKED (ctrl) )
1461 return gpg_error (GPG_ERR_LOCKED);
1463 line = skip_options (line);
1466 return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1468 while (*line && !spacep (line))
1472 if ((rc = open_card (ctrl, NULL)))
1476 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1478 chvnostr = xtrystrdup (chvnostr);
1480 return out_of_core ();
1481 rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
1483 log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1486 TEST_CARD_REMOVAL (ctrl, rc);
1491 static const char hlp_checkpin[] =
1492 "CHECKPIN <idstr>\n"
1494 "Perform a VERIFY operation without doing anything else. This may\n"
1495 "be used to initialize a the PIN cache earlier to long lasting\n"
1496 "operations. Its use is highly application dependent.\n"
1500 " Perform a simple verify operation for CHV1 and CHV2, so that\n"
1501 " further operations won't ask for CHV2 and it is possible to do a\n"
1502 " cheap check on the PIN: If there is something wrong with the PIN\n"
1503 " entry system, only the regular CHV will get blocked and not the\n"
1504 " dangerous CHV3. IDSTR is the usual card's serial number in hex\n"
1505 " notation; an optional fingerprint part will get ignored. There\n"
1506 " is however a special mode if the IDSTR is sffixed with the\n"
1507 " literal string \"[CHV3]\": In this case the Admin PIN is checked\n"
1508 " if and only if the retry counter is still at 3.\n"
1512 " Any of the valid PIN Ids may be used. These are the strings:\n"
1514 " PW1.CH - Global password 1\n"
1515 " PW2.CH - Global password 2\n"
1516 " PW1.CH.SIG - SigG password 1\n"
1517 " PW2.CH.SIG - SigG password 2\n"
1519 " For a definitive list, see the implementation in app-nks.c.\n"
1520 " Note that we call a PW2.* PIN a \"PUK\" despite that since TCOS\n"
1521 " 3.0 they are technically alternative PINs used to mutally\n"
1522 " unblock each other.";
1524 cmd_checkpin (assuan_context_t ctx, char *line)
1526 ctrl_t ctrl = assuan_get_pointer (ctx);
1530 if ( IS_LOCKED (ctrl) )
1531 return gpg_error (GPG_ERR_LOCKED);
1533 if ((rc = open_card (ctrl, NULL)))
1537 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1539 /* We have to use a copy of the key ID because the function may use
1540 the pin_cb which in turn uses the assuan line buffer and thus
1541 overwriting the original line with the keyid. */
1542 idstr = xtrystrdup (line);
1544 return out_of_core ();
1546 rc = app_check_pin (ctrl->app_ctx, idstr, pin_cb, ctx);
1549 log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1551 TEST_CARD_REMOVAL (ctrl, rc);
1556 static const char hlp_lock[] =
1559 "Grant exclusive card access to this session. Note that there is\n"
1560 "no lock counter used and a second lock from the same session will\n"
1561 "be ignored. A single unlock (or RESET) unlocks the session.\n"
1562 "Return GPG_ERR_LOCKED if another session has locked the reader.\n"
1564 "If the option --wait is given the command will wait until a\n"
1565 "lock has been released.";
1567 cmd_lock (assuan_context_t ctx, char *line)
1569 ctrl_t ctrl = assuan_get_pointer (ctx);
1575 if (locked_session != ctrl->server_local)
1576 rc = gpg_error (GPG_ERR_LOCKED);
1579 locked_session = ctrl->server_local;
1582 if (rc && has_option (line, "--wait"))
1585 npth_sleep (1); /* Better implement an event mechanism. However,
1586 for card operations this should be
1588 /* FIXME: Need to check that the connection is still alive.
1589 This can be done by issuing status messages. */
1595 log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1600 static const char hlp_unlock[] =
1603 "Release exclusive card access.";
1605 cmd_unlock (assuan_context_t ctx, char *line)
1607 ctrl_t ctrl = assuan_get_pointer (ctx);
1614 if (locked_session != ctrl->server_local)
1615 rc = gpg_error (GPG_ERR_LOCKED);
1617 locked_session = NULL;
1620 rc = gpg_error (GPG_ERR_NOT_LOCKED);
1623 log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1628 static const char hlp_getinfo[] =
1631 "Multi purpose command to return certain information. \n"
1632 "Supported values of WHAT are:\n"
1634 "version - Return the version of the program.\n"
1635 "pid - Return the process id of the server.\n"
1637 "socket_name - Return the name of the socket.\n"
1639 "status - Return the status of the current reader (in the future, may\n"
1640 "also return the status of all readers). The status is a list of\n"
1641 "one-character flags. The following flags are currently defined:\n"
1642 " 'u' Usable card present. This is the normal state during operation.\n"
1643 " 'r' Card removed. A reset is necessary.\n"
1644 "These flags are exclusive.\n"
1646 "reader_list - Return a list of detected card readers. Does\n"
1647 " currently only work with the internal CCID driver.\n"
1649 "deny_admin - Returns OK if admin commands are not allowed or\n"
1650 " GPG_ERR_GENERAL if admin commands are allowed.\n"
1652 "app_list - Return a list of supported applications. One\n"
1653 " application per line, fields delimited by colons,\n"
1654 " first field is the name.";
1656 cmd_getinfo (assuan_context_t ctx, char *line)
1660 if (!strcmp (line, "version"))
1662 const char *s = VERSION;
1663 rc = assuan_send_data (ctx, s, strlen (s));
1665 else if (!strcmp (line, "pid"))
1669 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1670 rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1672 else if (!strcmp (line, "socket_name"))
1674 const char *s = scd_get_socket_name ();
1677 rc = assuan_send_data (ctx, s, strlen (s));
1679 rc = gpg_error (GPG_ERR_NO_DATA);
1681 else if (!strcmp (line, "status"))
1683 ctrl_t ctrl = assuan_get_pointer (ctx);
1684 int vrdr = ctrl->server_local->vreader_idx;
1687 if (!ctrl->server_local->card_removed && vrdr != -1)
1689 struct vreader_s *vr;
1691 if (!(vrdr >= 0 && vrdr < DIM(vreader_table)))
1694 vr = &vreader_table[vrdr];
1695 if (vr->valid && vr->any && (vr->status & 1))
1698 rc = assuan_send_data (ctx, &flag, 1);
1700 else if (!strcmp (line, "reader_list"))
1703 char *s = ccid_get_reader_list ();
1709 rc = assuan_send_data (ctx, s, strlen (s));
1711 rc = gpg_error (GPG_ERR_NO_DATA);
1714 else if (!strcmp (line, "deny_admin"))
1715 rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1716 else if (!strcmp (line, "app_list"))
1718 char *s = get_supported_applications ();
1720 rc = assuan_send_data (ctx, s, strlen (s));
1726 rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1731 static const char hlp_restart[] =
1734 "Restart the current connection; this is a kind of warm reset. It\n"
1735 "deletes the context used by this connection but does not send a\n"
1736 "RESET to the card. Thus the card itself won't get reset. \n"
1738 "This is used by gpg-agent to reuse a primary pipe connection and\n"
1739 "may be used by clients to backup from a conflict in the serial\n"
1740 "command; i.e. to select another application.";
1742 cmd_restart (assuan_context_t ctx, char *line)
1744 ctrl_t ctrl = assuan_get_pointer (ctx);
1750 release_application (ctrl->app_ctx);
1751 ctrl->app_ctx = NULL;
1753 if (locked_session && ctrl->server_local == locked_session)
1755 locked_session = NULL;
1756 log_info ("implicitly unlocking due to RESTART\n");
1762 static const char hlp_disconnect[] =
1765 "Disconnect the card if it is not any longer used by other\n"
1766 "connections and the backend supports a disconnect operation.";
1768 cmd_disconnect (assuan_context_t ctx, char *line)
1770 ctrl_t ctrl = assuan_get_pointer (ctx);
1774 ctrl->server_local->disconnect_allowed = 1;
1780 static const char hlp_apdu[] =
1781 "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n"
1783 "Send an APDU to the current reader. This command bypasses the high\n"
1784 "level functions and sends the data directly to the card. HEXSTRING\n"
1785 "is expected to be a proper APDU. If HEXSTRING is not given no\n"
1786 "commands are set to the card but the command will implictly check\n"
1787 "whether the card is ready for use. \n"
1789 "Using the option \"--atr\" returns the ATR of the card as a status\n"
1790 "message before any data like this:\n"
1791 " S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1\n"
1793 "Using the option --more handles the card status word MORE_DATA\n"
1794 "(61xx) and concatenates all responses to one block.\n"
1796 "Using the option \"--exlen\" the returned APDU may use extended\n"
1797 "length up to N bytes. If N is not given a default value is used\n"
1798 "(currently 4096).";
1800 cmd_apdu (assuan_context_t ctx, char *line)
1802 ctrl_t ctrl = assuan_get_pointer (ctx);
1804 unsigned char *apdu;
1812 if (has_option (line, "--dump-atr"))
1815 with_atr = has_option (line, "--atr");
1816 handle_more = has_option (line, "--more");
1818 if ((s=has_option_name (line, "--exlen")))
1821 exlen = strtoul (s+1, NULL, 0);
1828 line = skip_options (line);
1830 if ( IS_LOCKED (ctrl) )
1831 return gpg_error (GPG_ERR_LOCKED);
1833 if ((rc = open_card (ctrl, NULL)))
1836 slot = vreader_slot (ctrl->server_local->vreader_idx);
1844 atr = apdu_get_atr (slot, &atrlen);
1845 if (!atr || atrlen > sizeof hexbuf - 2 )
1847 rc = gpg_error (GPG_ERR_INV_CARD);
1852 char *string, *p, *pend;
1854 string = atr_dump (atr, atrlen);
1857 for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1)
1859 rc = assuan_send_data (ctx, p, pend - p + 1);
1861 rc = assuan_send_data (ctx, NULL, 0);
1864 rc = assuan_send_data (ctx, p, strlen (p));
1872 bin2hex (atr, atrlen, hexbuf);
1873 send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1878 apdu = hex_to_buffer (line, &apdulen);
1881 rc = gpg_error_from_syserror ();
1886 unsigned char *result = NULL;
1889 rc = apdu_send_direct (slot, exlen,
1890 apdu, apdulen, handle_more,
1891 &result, &resultlen);
1893 log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1896 rc = assuan_send_data (ctx, result, resultlen);
1903 TEST_CARD_REMOVAL (ctrl, rc);
1908 static const char hlp_killscd[] =
1913 cmd_killscd (assuan_context_t ctx, char *line)
1915 ctrl_t ctrl = assuan_get_pointer (ctx);
1919 ctrl->server_local->stopme = 1;
1920 assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
1926 /* Tell the assuan library about our commands */
1928 register_commands (assuan_context_t ctx)
1932 assuan_handler_t handler;
1933 const char * const help;
1935 { "SERIALNO", cmd_serialno, hlp_serialno },
1936 { "LEARN", cmd_learn, hlp_learn },
1937 { "READCERT", cmd_readcert, hlp_readcert },
1938 { "READKEY", cmd_readkey, hlp_readkey },
1939 { "SETDATA", cmd_setdata, hlp_setdata },
1940 { "PKSIGN", cmd_pksign, hlp_pksign },
1941 { "PKAUTH", cmd_pkauth, hlp_pkauth },
1942 { "PKDECRYPT", cmd_pkdecrypt,hlp_pkdecrypt },
1945 { "GETATTR", cmd_getattr, hlp_getattr },
1946 { "SETATTR", cmd_setattr, hlp_setattr },
1947 { "WRITECERT", cmd_writecert,hlp_writecert },
1948 { "WRITEKEY", cmd_writekey, hlp_writekey },
1949 { "GENKEY", cmd_genkey, hlp_genkey },
1950 { "RANDOM", cmd_random, hlp_random },
1951 { "PASSWD", cmd_passwd, hlp_passwd },
1952 { "CHECKPIN", cmd_checkpin, hlp_checkpin },
1953 { "LOCK", cmd_lock, hlp_lock },
1954 { "UNLOCK", cmd_unlock, hlp_unlock },
1955 { "GETINFO", cmd_getinfo, hlp_getinfo },
1956 { "RESTART", cmd_restart, hlp_restart },
1957 { "DISCONNECT", cmd_disconnect,hlp_disconnect },
1958 { "APDU", cmd_apdu, hlp_apdu },
1959 { "KILLSCD", cmd_killscd, hlp_killscd },
1964 for (i=0; table[i].name; i++)
1966 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
1971 assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1973 assuan_register_reset_notify (ctx, reset_notify);
1974 assuan_register_option_handler (ctx, option_handler);
1979 /* Startup the server. If FD is given as -1 this is simple pipe
1980 server, otherwise it is a regular server. Returns true if there
1981 are no more active asessions. */
1983 scd_command_handler (ctrl_t ctrl, int fd)
1986 assuan_context_t ctx = NULL;
1989 rc = assuan_new (&ctx);
1992 log_error ("failed to allocate assuan context: %s\n",
1999 assuan_fd_t filedes[2];
2001 filedes[0] = assuan_fdopen (0);
2002 filedes[1] = assuan_fdopen (1);
2003 rc = assuan_init_pipe_server (ctx, filedes);
2007 rc = assuan_init_socket_server (ctx, INT2FD(fd),
2008 ASSUAN_SOCKET_SERVER_ACCEPTED);
2012 log_error ("failed to initialize the server: %s\n",
2016 rc = register_commands (ctx);
2019 log_error ("failed to register commands with Assuan: %s\n",
2023 assuan_set_pointer (ctx, ctrl);
2025 /* Allocate and initialize the server object. Put it into the list
2026 of active sessions. */
2027 ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2028 ctrl->server_local->next_session = session_list;
2029 session_list = ctrl->server_local;
2030 ctrl->server_local->ctrl_backlink = ctrl;
2031 ctrl->server_local->assuan_ctx = ctx;
2032 ctrl->server_local->vreader_idx = -1;
2034 /* We open the reader right at startup so that the ticker is able to
2035 update the status file. */
2036 if (ctrl->server_local->vreader_idx == -1)
2038 ctrl->server_local->vreader_idx = get_current_reader ();
2041 /* Command processing loop. */
2044 rc = assuan_accept (ctx);
2051 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2055 rc = assuan_process (ctx);
2058 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2063 /* Cleanup. We don't send an explicit reset to the card. */
2066 /* Release the server object. */
2067 if (session_list == ctrl->server_local)
2068 session_list = ctrl->server_local->next_session;
2071 struct server_local_s *sl;
2073 for (sl=session_list; sl->next_session; sl = sl->next_session)
2074 if (sl->next_session == ctrl->server_local)
2076 if (!sl->next_session)
2078 sl->next_session = ctrl->server_local->next_session;
2080 stopme = ctrl->server_local->stopme;
2081 xfree (ctrl->server_local);
2082 ctrl->server_local = NULL;
2084 /* Release the Assuan context. */
2085 assuan_release (ctx);
2090 /* If there are no more sessions return true. */
2091 return !session_list;
2095 /* Send a line with status information via assuan and escape all given
2096 buffers. The variable elements are pairs of (char *, size_t),
2097 terminated with a (NULL, 0). */
2099 send_status_info (ctrl_t ctrl, const char *keyword, ...)
2102 const unsigned char *value;
2106 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2108 va_start (arg_ptr, keyword);
2112 while ( (value = va_arg (arg_ptr, const unsigned char *)) )
2114 valuelen = va_arg (arg_ptr, size_t);
2116 continue; /* empty buffer */
2122 for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
2124 if (*value < ' ' || *value == '+')
2126 sprintf (p, "%%%02X", *value);
2129 else if (*value == ' ')
2136 assuan_write_status (ctx, keyword, buf);
2142 /* Send a ready formatted status line via assuan. */
2144 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
2146 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2148 if (strchr (args, '\n'))
2149 log_error ("error: LF detected in status line - not sending\n");
2151 assuan_write_status (ctx, keyword, args);
2155 /* Helper to send the clients a status change notification. */
2157 send_client_notifications (void)
2161 #ifdef HAVE_W32_SYSTEM
2169 struct server_local_s *sl;
2171 for (sl=session_list; sl; sl = sl->next_session)
2173 if (sl->event_signal && sl->assuan_ctx)
2175 pid_t pid = assuan_get_pid (sl->assuan_ctx);
2176 #ifdef HAVE_W32_SYSTEM
2177 HANDLE handle = (void *)sl->event_signal;
2179 for (kidx=0; kidx < killidx; kidx++)
2180 if (killed[kidx].pid == pid
2181 && killed[kidx].handle == handle)
2184 log_info ("event %lx (%p) already triggered for client %d\n",
2185 sl->event_signal, handle, (int)pid);
2188 log_info ("triggering event %lx (%p) for client %d\n",
2189 sl->event_signal, handle, (int)pid);
2190 if (!SetEvent (handle))
2191 log_error ("SetEvent(%lx) failed: %s\n",
2192 sl->event_signal, w32_strerror (-1));
2193 if (killidx < DIM (killed))
2195 killed[killidx].pid = pid;
2196 killed[killidx].handle = handle;
2200 #else /*!HAVE_W32_SYSTEM*/
2201 int signo = sl->event_signal;
2203 if (pid != (pid_t)(-1) && pid && signo > 0)
2205 for (kidx=0; kidx < killidx; kidx++)
2206 if (killed[kidx].pid == pid
2207 && killed[kidx].signo == signo)
2210 log_info ("signal %d already sent to client %d\n",
2214 log_info ("sending signal %d to client %d\n",
2217 if (killidx < DIM (killed))
2219 killed[killidx].pid = pid;
2220 killed[killidx].signo = signo;
2225 #endif /*!HAVE_W32_SYSTEM*/
2232 /* This is the core of scd_update_reader_status_file but the caller
2233 needs to take care of the locking. */
2235 update_reader_status_file (int set_card_removed_flag)
2238 unsigned int status, changed;
2240 /* Note, that we only try to get the status, because it does not
2241 make sense to wait here for a operation to complete. If we are
2242 busy working with a card, delays in the status file update should
2244 for (idx=0; idx < DIM(vreader_table); idx++)
2246 struct vreader_s *vr = vreader_table + idx;
2247 struct server_local_s *sl;
2250 if (!vr->valid || vr->slot == -1)
2251 continue; /* Not valid or reader not yet open. */
2253 sw_apdu = apdu_get_status (vr->slot, 0, &status, &changed);
2254 if (sw_apdu == SW_HOST_NO_READER)
2256 /* Most likely the _reader_ has been unplugged. */
2257 application_notify_card_reset (vr->slot);
2258 apdu_close_reader (vr->slot);
2261 changed = vr->changed;
2265 /* Get status failed. Ignore that. */
2269 if (!vr->any || vr->status != status || vr->changed != changed )
2275 log_info ("updating reader %d (%d) status: 0x%04X->0x%04X (%u->%u)\n",
2276 idx, vr->slot, vr->status, status, vr->changed, changed);
2277 vr->status = status;
2278 vr->changed = changed;
2280 /* FIXME: Should this be IDX instead of vr->slot? This
2281 depends on how client sessions will associate the reader
2282 status with their session. */
2283 snprintf (templ, sizeof templ, "reader_%d.status", vr->slot);
2284 fname = make_filename (opt.homedir, templ, NULL );
2285 fp = fopen (fname, "w");
2288 fprintf (fp, "%s\n",
2289 (status & 1)? "USABLE":
2290 (status & 4)? "ACTIVE":
2291 (status & 2)? "PRESENT": "NOCARD");
2296 /* If a status script is executable, run it. */
2298 const char *args[9], *envs[2];
2299 char numbuf1[30], numbuf2[30], numbuf3[30];
2300 char *homestr, *envstr;
2303 homestr = make_filename (opt.homedir, NULL);
2304 if (gpgrt_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
2305 log_error ("out of core while building environment\n");
2311 sprintf (numbuf1, "%d", vr->slot);
2312 sprintf (numbuf2, "0x%04X", vr->status);
2313 sprintf (numbuf3, "0x%04X", status);
2314 args[0] = "--reader-port";
2316 args[2] = "--old-code";
2318 args[4] = "--new-code";
2320 args[6] = "--status";
2321 args[7] = ((status & 1)? "USABLE":
2322 (status & 4)? "ACTIVE":
2323 (status & 2)? "PRESENT": "NOCARD");
2326 fname = make_filename (opt.homedir, "scd-event", NULL);
2327 err = gnupg_spawn_process_detached (fname, args, envs);
2328 if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
2329 log_error ("failed to run event handler '%s': %s\n",
2330 fname, gpg_strerror (err));
2337 /* Set the card removed flag for all current sessions. */
2338 if (vr->any && vr->status == 0 && set_card_removed_flag)
2339 update_card_removed (idx, 1);
2343 /* Send a signal to all clients who applied for it. */
2344 send_client_notifications ();
2347 /* Check whether a disconnect is pending. */
2348 if (opt.card_timeout)
2350 for (sl=session_list; sl; sl = sl->next_session)
2351 if (!sl->disconnect_allowed)
2353 if (session_list && !sl)
2355 /* FIXME: Use a real timeout. */
2356 /* At least one connection and all allow a disconnect. */
2357 log_info ("disconnecting card in reader %d (%d)\n",
2359 apdu_disconnect (vr->slot);
2366 /* This function is called by the ticker thread to check for changes
2367 of the reader stati. It updates the reader status files and if
2368 requested by the caller also send a signal to the caller. */
2370 scd_update_reader_status_file (void)
2373 err = npth_mutex_lock (&status_file_update_lock);
2375 return; /* locked - give up. */
2376 update_reader_status_file (1);
2377 err = npth_mutex_unlock (&status_file_update_lock);
2379 log_error ("failed to release status_file_update lock: %s\n",