1
/* command.c - SCdaemon command handler
2
* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4
* This file is part of GnuPG.
6
* GnuPG is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* GnuPG is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
34
#include "app-common.h"
35
#include "apdu.h" /* Required for apdu_*_reader (). */
37
/* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
38
#define MAXLEN_PIN 100
41
/* We keep track of the primary client using scdaemon. This one will
42
for example receive signal on card change. */
43
static ctrl_t primary_connection;
46
#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
48
/* Data used to associate an Assuan context with local server data */
49
struct server_local_s {
50
ASSUAN_CONTEXT assuan_ctx;
51
int event_signal; /* Or 0 if not used. */
55
/* Check whether the option NAME appears in LINE */
57
has_option (const char *line, const char *name)
60
int n = strlen (name);
62
s = strstr (line, name);
63
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
67
/* Reset the card and free the application context. With DO_CLOSE set
68
to true, close the reader and don't do just a reset. */
70
do_reset (ctrl_t ctrl, int do_close)
74
card_close (ctrl->card_ctx);
75
ctrl->card_ctx = NULL;
76
xfree (ctrl->in_data.value);
77
ctrl->in_data.value = NULL;
81
release_application (ctrl->app_ctx);
84
if (ctrl->reader_slot != -1)
86
if (do_close || apdu_reset (ctrl->reader_slot))
88
apdu_close_reader (ctrl->reader_slot);
89
ctrl->reader_slot = -1;
96
reset_notify (ASSUAN_CONTEXT ctx)
98
CTRL ctrl = assuan_get_pointer (ctx);
105
option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
107
ctrl_t ctrl = assuan_get_pointer (ctx);
109
if (!strcmp (key, "event-signal"))
111
/* A value of 0 is allowed to reset the event signal. */
112
int i = *value? atoi (value) : -1;
114
return ASSUAN_Parameter_Error;
115
ctrl->server_local->event_signal = i;
122
/* If the card has not yet been opened, do it. Note that this
123
function returns an Assuan error, so don't map the error a second
126
open_card (ctrl_t ctrl, const char *apptype)
131
return 0; /* Already initialized for one specific application. */
133
return 0; /* Already initialized using a card context. */
135
if (ctrl->reader_slot != -1)
136
slot = ctrl->reader_slot;
138
slot = apdu_open_reader (opt.reader_port);
139
ctrl->reader_slot = slot;
141
ctrl->app_ctx = select_application (ctrl, slot, apptype);
143
{ /* No application found - fall back to old mode. */
144
/* Note that we should rework the old code to use the
145
application paradigma too. */
148
/* If an APPTYPE was requested and it is not pkcs#15, we return
150
if (apptype && !(!strcmp (apptype, "P15") || !strcmp (apptype, "p15")))
151
rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
153
rc = card_open (&ctrl->card_ctx);
155
return map_to_assuan_status (rc);
161
/* Do the percent and plus/space unescaping in place and return the
162
length of the valid buffer. */
164
percent_plus_unescape (unsigned char *string)
166
unsigned char *p = string;
171
if (*string == '%' && string[1] && string[2])
174
*p++ = xtoi_2 (string);
178
else if (*string == '+')
196
/* SERIALNO [APPTYPE]
198
Return the serial number of the card using a status reponse. This
199
functon should be used to check for the presence of a card.
201
If APPTYPE is given, an application of that type is selected and an
202
error is returned if the application is not supported or available.
203
The default is to auto-select the application using a hardwired
204
preference system. Note, that a future extension to this function
205
may allow to specify a list and order of applications to try.
207
This function is special in that it can be used to reset the card.
208
Most other functions will return an error when a card change has
209
been detected and the use of this function is therefore required.
211
Background: We want to keep the client clear of handling card
212
changes between operations; i.e. the client can assume that all
213
operations are done on the same card unless he calls this function.
216
cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
218
CTRL ctrl = assuan_get_pointer (ctx);
220
char *serial_and_stamp;
224
if ((rc = open_card (ctrl, *line? line:NULL)))
228
rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
230
rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
232
return map_to_assuan_status (rc);
233
rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
236
return ASSUAN_Out_Of_Core;
238
assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
239
free (serial_and_stamp);
248
Learn all useful information of the currently inserted card. When
249
used without the force options, the command might do an INQUIRE
252
INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>
254
The client should just send an "END" if the processing should go on
255
or a "CANCEL" to force the function to terminate with a Cancel
256
error message. The response of this command is a list of status
257
lines formatted as this:
261
This returns the type of the application, currently the strings:
263
P15 = PKCS-15 structure used
265
OPENPGP = OpenPGP card
267
are implemented. These strings are aliases for the AID
269
S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
271
If there is no certificate yet stored on the card a single "X" is
272
returned as the keygrip. In addition to the keypair info, information
273
about all certificates stored on the card is also returned:
275
S CERTINFO <certtype> <hexstring_with_id>
277
Where CERTTYPE is a number indicating the type of certificate:
279
100 := Regular X.509 cert
280
101 := Trusted X.509 cert
281
102 := Useful X.509 cert
282
110 := Root CA cert (DINSIG)
284
For certain cards, more information will be returned:
286
S KEY-FPR <no> <hexstring>
288
For OpenPGP cards this returns the stored fingerprints of the
289
keys. This can be used check whether a key is available on the
290
card. NO may be 1, 2 or 3.
292
S CA-FPR <no> <hexstring>
294
Similar to above, these are the fingerprints of keys assumed to be
297
S DISP-NAME <name_of_card_holder>
299
The name of the card holder as stored on the card; percent
300
escaping takes place, spaces are encoded as '+'
304
The URL to be used for locating the entire public key.
308
cmd_learn (ASSUAN_CONTEXT ctx, char *line)
310
CTRL ctrl = assuan_get_pointer (ctx);
314
if ((rc = open_card (ctrl, NULL)))
317
/* Unless the force option is used we try a shortcut by identifying
318
the card using a serial number and inquiring the client with
319
that. The client may choose to cancel the operation if he already
320
knows about this card */
322
char *serial_and_stamp;
327
rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
329
rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
331
return map_to_assuan_status (rc);
332
rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
335
return ASSUAN_Out_Of_Core;
337
assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
339
if (!has_option (line, "--force"))
343
rc = asprintf (&command, "KNOWNCARDP %s", serial_and_stamp);
346
free (serial_and_stamp);
347
return ASSUAN_Out_Of_Core;
350
rc = assuan_inquire (ctx, command, NULL, NULL, 0);
351
free (command); /* (must use standard free here) */
354
if (rc != ASSUAN_Canceled)
355
log_error ("inquire KNOWNCARDP failed: %s\n",
356
assuan_strerror (rc));
357
free (serial_and_stamp);
360
/* not canceled, so we have to proceeed */
362
free (serial_and_stamp);
365
/* If we are using the modern application paradigma, let the
366
application print out its collection of useful status
368
if (!rc && ctrl->app_ctx)
369
rc = app_write_learn_status (ctrl->app_ctx, ctrl);
371
/* Return information about the certificates. FIXME: Move this into
373
for (idx=0; !rc && !ctrl->app_ctx; idx++)
378
rc = card_enum_certs (ctrl->card_ctx, idx, &certid, &certtype);
383
buf = xtrymalloc (40 + 1 + strlen (certid) + 1);
385
rc = gpg_error (gpg_err_code_from_errno (errno));
388
sprintf (buf, "%d %s", certtype, certid);
389
assuan_write_status (ctx, "CERTINFO", buf);
398
/* Return information about the keys. FIXME: Move this into an
400
for (idx=0; !rc && !ctrl->app_ctx; idx++)
402
unsigned char keygrip[20];
406
rc = card_enum_keypairs (ctrl->card_ctx, idx, keygrip, &keyid);
407
if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT && keyid)
409
/* This does happen with an incomplete personalized
410
card; i.e. during the time we have stored the key on the
411
card but not stored the certificate; probably becuase it
412
has not yet been received back from the CA. Note that we
413
must release KEYID in this case. */
421
buf = p = xtrymalloc (40 + 1 + strlen (keyid) + 1);
423
rc = gpg_error (gpg_err_code_from_errno (errno));
432
for (i=0; i < 20; i++, p += 2)
433
sprintf (p, "%02X", keygrip[i]);
437
assuan_write_status (ctx, "KEYPAIRINFO", buf);
446
return map_to_assuan_status (rc);
451
/* READCERT <hexified_certid>
455
cmd_readcert (ASSUAN_CONTEXT ctx, char *line)
457
CTRL ctrl = assuan_get_pointer (ctx);
462
if ((rc = open_card (ctrl, NULL)))
465
line = xstrdup (line); /* Need a copy of the line. */
468
rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
470
log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
474
rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
476
log_error ("card_read_cert failed: %s\n", gpg_strerror (rc));
482
rc = assuan_send_data (ctx, cert, ncert);
488
return map_to_assuan_status (rc);
492
/* READKEY <hexified_certid>
494
Return the public key for the given cert or key ID as an standard
497
cmd_readkey (ASSUAN_CONTEXT ctx, char *line)
499
CTRL ctrl = assuan_get_pointer (ctx);
501
unsigned char *cert = NULL;
503
ksba_cert_t kc = NULL;
506
if ((rc = open_card (ctrl, NULL)))
509
line = xstrdup (line); /* Need a copy of the line. */
512
rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
514
log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
518
rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
520
log_error ("card_read_cert failed: %s\n", gpg_strerror (rc));
527
rc = ksba_cert_new (&kc);
533
rc = ksba_cert_init_from_mem (kc, cert, ncert);
536
log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
540
p = ksba_cert_get_public_key (kc);
543
rc = gpg_error (GPG_ERR_NO_PUBKEY);
547
n = gcry_sexp_canon_len (p, 0, NULL, NULL);
548
rc = assuan_send_data (ctx, p, n);
549
rc = map_assuan_err (rc);
554
ksba_cert_release (kc);
556
return map_to_assuan_status (rc);
562
/* SETDATA <hexstring>
564
The client should use this command to tell us the data he want to
567
cmd_setdata (ASSUAN_CONTEXT ctx, char *line)
569
CTRL ctrl = assuan_get_pointer (ctx);
574
/* parse the hexstring */
575
for (p=line,n=0; hexdigitp (p); p++, n++)
578
return set_error (Parameter_Error, "invalid hexstring");
580
return set_error (Parameter_Error, "no data given");
582
return set_error (Parameter_Error, "odd number of digits");
584
buf = xtrymalloc (n);
586
return ASSUAN_Out_Of_Core;
588
ctrl->in_data.value = buf;
589
ctrl->in_data.valuelen = n;
590
for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++)
598
pin_cb (void *opaque, const char *info, char **retstr)
600
ASSUAN_CONTEXT ctx = opaque;
603
unsigned char *value;
607
log_debug ("asking for PIN '%s'\n", info);
609
rc = asprintf (&command, "NEEDPIN %s", info);
611
return gpg_error (gpg_err_code_from_errno (errno));
613
/* FIXME: Write an inquire function which returns the result in
615
rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
618
return map_assuan_err (rc);
620
if (!valuelen || value[valuelen-1])
622
/* We require that the returned value is an UTF-8 string */
624
return gpg_error (GPG_ERR_INV_RESPONSE);
631
/* PKSIGN <hexified_id>
635
cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
637
CTRL ctrl = assuan_get_pointer (ctx);
639
unsigned char *outdata;
643
if ((rc = open_card (ctrl, NULL)))
646
/* We have to use a copy of the key ID because the function may use
647
the pin_cb which in turn uses the assuan line buffer and thus
648
overwriting the original line with the keyid */
649
keyidstr = xtrystrdup (line);
651
return ASSUAN_Out_Of_Core;
654
rc = app_sign (ctrl->app_ctx,
655
keyidstr, GCRY_MD_SHA1,
657
ctrl->in_data.value, ctrl->in_data.valuelen,
658
&outdata, &outdatalen);
660
rc = card_sign (ctrl->card_ctx,
661
keyidstr, GCRY_MD_SHA1,
663
ctrl->in_data.value, ctrl->in_data.valuelen,
664
&outdata, &outdatalen);
668
log_error ("card_sign failed: %s\n", gpg_strerror (rc));
672
rc = assuan_send_data (ctx, outdata, outdatalen);
675
return rc; /* that is already an assuan error code */
678
return map_to_assuan_status (rc);
681
/* PKAUTH <hexified_id>
685
cmd_pkauth (ASSUAN_CONTEXT ctx, char *line)
687
CTRL ctrl = assuan_get_pointer (ctx);
689
unsigned char *outdata;
693
if ((rc = open_card (ctrl, NULL)))
697
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
699
/* We have to use a copy of the key ID because the function may use
700
the pin_cb which in turn uses the assuan line buffer and thus
701
overwriting the original line with the keyid */
702
keyidstr = xtrystrdup (line);
704
return ASSUAN_Out_Of_Core;
706
rc = app_auth (ctrl->app_ctx,
709
ctrl->in_data.value, ctrl->in_data.valuelen,
710
&outdata, &outdatalen);
714
log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc));
718
rc = assuan_send_data (ctx, outdata, outdatalen);
721
return rc; /* that is already an assuan error code */
724
return map_to_assuan_status (rc);
727
/* PKDECRYPT <hexified_id>
731
cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
733
CTRL ctrl = assuan_get_pointer (ctx);
735
unsigned char *outdata;
739
if ((rc = open_card (ctrl, NULL)))
742
keyidstr = xtrystrdup (line);
744
return ASSUAN_Out_Of_Core;
746
rc = app_decipher (ctrl->app_ctx,
749
ctrl->in_data.value, ctrl->in_data.valuelen,
750
&outdata, &outdatalen);
752
rc = card_decipher (ctrl->card_ctx,
755
ctrl->in_data.value, ctrl->in_data.valuelen,
756
&outdata, &outdatalen);
760
log_error ("card_create_signature failed: %s\n", gpg_strerror (rc));
764
rc = assuan_send_data (ctx, outdata, outdatalen);
767
return rc; /* that is already an assuan error code */
770
return map_to_assuan_status (rc);
776
This command is used to retrieve data from a smartcard. The
777
allowed names depend on the currently selected smartcard
778
application. NAME must be percent and '+' escaped. The value is
779
returned through status message, see the LESRN command for details.
781
However, the current implementation assumes that Name is not escaped;
782
this works as long as noone uses arbitrary escaping.
786
cmd_getattr (ASSUAN_CONTEXT ctx, char *line)
788
CTRL ctrl = assuan_get_pointer (ctx);
792
if ((rc = open_card (ctrl, NULL)))
796
for (; *line && !spacep (line); line++)
801
/* (We ignore any garbage for now.) */
803
rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
805
return map_to_assuan_status (rc);
809
/* SETATTR <name> <value>
811
This command is used to store data on a a smartcard. The allowed
812
names and values are depend on the currently selected smartcard
813
application. NAME and VALUE must be percent and '+' escaped.
815
However, the curent implementation assumes that Name is not escaped;
816
this works as long as noone uses arbitrary escaping.
818
A PIN will be requested for most NAMEs. See the corresponding
819
setattr function of the actually used application (app-*.c) for
822
cmd_setattr (ASSUAN_CONTEXT ctx, char *orig_line)
824
CTRL ctrl = assuan_get_pointer (ctx);
829
char *line, *linebuf;
831
if ((rc = open_card (ctrl, NULL)))
834
/* We need to use a copy of LINE, because PIN_CB uses the same
835
context and thus reuses the Assuan provided LINE. */
836
line = linebuf = xtrystrdup (orig_line);
838
return ASSUAN_Out_Of_Core;
841
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
845
while (spacep (line))
847
nbytes = percent_plus_unescape (line);
849
rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, line, nbytes);
852
return map_to_assuan_status (rc);
855
/* GENKEY [--force] <no>
857
Generate a key on-card identified by NO, which is application
858
specific. Return values are application specific. For OpenPGP
859
cards 2 status lines are returned:
861
S KEY-FPR <hexstring>
862
S KEY-CREATED-AT <seconds_since_epoch>
863
S KEY-DATA [p|n] <hexdata>
866
--force is required to overwriet an already existing key. The
867
KEY-CREATED-AT is required for further processing because it is
868
part of the hashed key material for the fingerprint.
870
The public part of the key can also later be retrieved using the
875
cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
877
CTRL ctrl = assuan_get_pointer (ctx);
880
int force = has_option (line, "--force");
882
/* Skip over options. */
883
while ( *line == '-' && line[1] == '-' )
885
while (*line && !spacep (line))
887
while (spacep (line))
891
return set_error (Parameter_Error, "no key number given");
893
while (*line && !spacep (line))
897
if ((rc = open_card (ctrl, NULL)))
901
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
903
keyno = xtrystrdup (keyno);
905
return ASSUAN_Out_Of_Core;
906
rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, pin_cb, ctx);
908
return map_to_assuan_status (rc);
914
Get NBYTES of random from the card and send them back as data.
917
cmd_random (ASSUAN_CONTEXT ctx, char *line)
919
CTRL ctrl = assuan_get_pointer (ctx);
922
unsigned char *buffer;
925
return set_error (Parameter_Error, "number of requested bytes missing");
926
nbytes = strtoul (line, NULL, 0);
928
if ((rc = open_card (ctrl, NULL)))
932
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
934
buffer = xtrymalloc (nbytes);
936
return ASSUAN_Out_Of_Core;
938
rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
941
rc = assuan_send_data (ctx, buffer, nbytes);
943
return rc; /* that is already an assuan error code */
947
return map_to_assuan_status (rc);
951
/* PASSWD [--reset] <chvno>
953
Change the PIN or reset thye retry counter of the card holder
954
verfication vector CHVNO. */
956
cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
958
CTRL ctrl = assuan_get_pointer (ctx);
961
int reset_mode = has_option (line, "--reset");
963
/* Skip over options. */
964
while (*line == '-' && line[1] == '-')
966
while (*line && !spacep (line))
968
while (spacep (line))
972
return set_error (Parameter_Error, "no CHV number given");
974
while (*line && !spacep (line))
978
if ((rc = open_card (ctrl, NULL)))
982
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
984
chvnostr = xtrystrdup (chvnostr);
986
return ASSUAN_Out_Of_Core;
987
rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, reset_mode, pin_cb, ctx);
989
log_error ("command passwd failed: %s\n", gpg_strerror (rc));
991
return map_to_assuan_status (rc);
995
/* CHECKPIN <hexified_id>
999
cmd_checkpin (ASSUAN_CONTEXT ctx, char *line)
1001
CTRL ctrl = assuan_get_pointer (ctx);
1005
if ((rc = open_card (ctrl, NULL)))
1009
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1011
/* We have to use a copy of the key ID because the function may use
1012
the pin_cb which in turn uses the assuan line buffer and thus
1013
overwriting the original line with the keyid. */
1014
keyidstr = xtrystrdup (line);
1016
return ASSUAN_Out_Of_Core;
1018
rc = app_check_pin (ctrl->app_ctx,
1023
log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1025
return map_to_assuan_status (rc);
1032
/* Tell the assuan library about our commands */
1034
register_commands (ASSUAN_CONTEXT ctx)
1038
int (*handler)(ASSUAN_CONTEXT, char *line);
1040
{ "SERIALNO", cmd_serialno },
1041
{ "LEARN", cmd_learn },
1042
{ "READCERT", cmd_readcert },
1043
{ "READKEY", cmd_readkey },
1044
{ "SETDATA", cmd_setdata },
1045
{ "PKSIGN", cmd_pksign },
1046
{ "PKAUTH", cmd_pkauth },
1047
{ "PKDECRYPT", cmd_pkdecrypt },
1050
{ "GETATTR", cmd_getattr },
1051
{ "SETATTR", cmd_setattr },
1052
{ "GENKEY", cmd_genkey },
1053
{ "RANDOM", cmd_random },
1054
{ "PASSWD", cmd_passwd },
1055
{ "CHECKPIN", cmd_checkpin },
1060
for (i=0; table[i].name; i++)
1062
rc = assuan_register_command (ctx, table[i].name, table[i].handler);
1066
assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1068
assuan_register_reset_notify (ctx, reset_notify);
1069
assuan_register_option_handler (ctx, option_handler);
1074
/* Startup the server. If LISTEN_FD is given as -1, this is simple
1075
piper server, otherwise it is a regular server */
1077
scd_command_handler (int listen_fd)
1081
struct server_control_s ctrl;
1083
memset (&ctrl, 0, sizeof ctrl);
1084
scd_init_default_ctrl (&ctrl);
1086
if (listen_fd == -1)
1092
rc = assuan_init_pipe_server (&ctx, filedes);
1096
rc = assuan_init_socket_server (&ctx, listen_fd);
1100
log_error ("failed to initialize the server: %s\n",
1101
assuan_strerror(rc));
1104
rc = register_commands (ctx);
1107
log_error ("failed to register commands with Assuan: %s\n",
1108
assuan_strerror(rc));
1111
assuan_set_pointer (ctx, &ctrl);
1112
ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local);
1113
ctrl.server_local->assuan_ctx = ctx;
1116
assuan_set_log_stream (ctx, log_get_stream ());
1118
/* Store the primary connection's assuan context. */
1119
if (!primary_connection)
1120
primary_connection = &ctrl;
1122
/* We open the reader right at startup so that the ticker is able to
1123
update the status file. */
1124
if (ctrl.reader_slot == -1)
1125
ctrl.reader_slot = apdu_open_reader (opt.reader_port);
1127
/* Command processing loop. */
1130
rc = assuan_accept (ctx);
1137
log_info ("Assuan accept problem: %s\n", assuan_strerror (rc));
1141
rc = assuan_process (ctx);
1144
log_info ("Assuan processing failed: %s\n", assuan_strerror (rc));
1149
/* The next client will be the primary conenction if this one
1151
if (primary_connection == &ctrl)
1152
primary_connection = NULL;
1154
do_reset (&ctrl, 1); /* Cleanup. */
1156
assuan_deinit_server (ctx);
1160
/* Send a line with status information via assuan and escape all given
1161
buffers. The variable elements are pairs of (char *, size_t),
1162
terminated with a (NULL, 0). */
1164
send_status_info (CTRL ctrl, const char *keyword, ...)
1167
const unsigned char *value;
1171
ASSUAN_CONTEXT ctx = ctrl->server_local->assuan_ctx;
1173
va_start (arg_ptr, keyword);
1177
while ( (value = va_arg (arg_ptr, const unsigned char *)) )
1179
valuelen = va_arg (arg_ptr, size_t);
1181
continue; /* empty buffer */
1187
for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
1189
if (*value < ' ' || *value == '+')
1191
sprintf (p, "%%%02X", *value);
1194
else if (*value == ' ')
1201
assuan_write_status (ctx, keyword, buf);
1209
scd_update_reader_status_file (void)
1213
unsigned int status;
1214
unsigned int changed;
1218
unsigned int status, changed;
1220
/* Note, that we only try to get the status, becuase it does not
1221
make sense to wait here for a operation to complete. If we are
1222
so busy working with the card, delays in the status file updated
1223
are should be acceptable. */
1224
for (slot=0; (slot < DIM(last)
1225
&&!apdu_enum_reader (slot, &used)); slot++)
1226
if (used && !apdu_get_status (slot, 0, &status, &changed))
1228
if (!last[slot].any || last[slot].status != status
1229
|| last[slot].changed != changed )
1236
last[slot].status = status;
1237
last[slot].changed = changed;
1239
log_info ("updating status of slot %d to 0x%04X\n", slot, status);
1241
sprintf (templ, "reader_%d.status", slot);
1242
fname = make_filename (opt.homedir, templ, NULL );
1243
fp = fopen (fname, "w");
1246
fprintf (fp, "%s\n",
1247
(status & 1)? "USABLE":
1248
(status & 4)? "ACTIVE":
1249
(status & 2)? "PRESENT": "NOCARD");
1254
/* Send a signal to the primary client, if any. */
1255
if (primary_connection && primary_connection->server_local
1256
&& primary_connection->server_local->assuan_ctx)
1258
pid_t pid = assuan_get_pid (primary_connection
1259
->server_local->assuan_ctx);
1260
int signo = primary_connection->server_local->event_signal;
1262
log_info ("client pid is %d, sending signal %d\n", pid, signo);
1264
#ifndef HAVE_W32_SYSTEM
1265
if (pid != (pid_t)(-1) && pid && signo > 0)