45
46
#define MAXLEN_KEYDATA 4096
48
#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
49
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
51
52
/* Macro to flag a removed card. */
107
/* The table with information on all used slots. */
108
/* The table with information on all used slots. FIXME: This is a
109
different slot number than the one used by the APDU layer, and
110
should be renamed. */
108
111
static struct slot_status_s slot_table[10];
229
231
if (!pth_mutex_acquire (&status_file_update_lock, 0, NULL))
231
233
log_error ("failed to acquire status_fle_update lock\n");
234
ctrl->reader_slot = -1;
234
237
update_reader_status_file ();
235
238
update_card_removed (slot, 0);
236
239
if (!pth_mutex_release (&status_file_update_lock))
237
240
log_error ("failed to release status_file_update lock\n");
242
/* Do this last, so that update_card_removed does its job. */
243
ctrl->reader_slot = -1;
257
263
/* A value of 0 is allowed to reset the event signal. */
258
264
int i = *value? atoi (value) : -1;
260
return ASSUAN_Parameter_Error;
266
return gpg_error (GPG_ERR_ASS_PARAMETER);
261
267
ctrl->server_local->event_signal = i;
287
293
if (ss->slot == -1)
288
294
ss->slot = apdu_open_reader (opt.reader_port);
296
/* Return the slot_table index. */
293
300
/* If the card has not yet been opened, do it. Note that this
294
301
function returns an Assuan error, so don't map the error a second
296
303
static assuan_error_t
297
304
open_card (ctrl_t ctrl, const char *apptype)
303
310
the SERIALNO command and a reset are able to clear from that
305
312
if (ctrl->server_local->card_removed)
306
return map_to_assuan_status (gpg_error (GPG_ERR_CARD_REMOVED));
313
return gpg_error (GPG_ERR_CARD_REMOVED);
308
315
if ( IS_LOCKED (ctrl) )
309
316
return gpg_error (GPG_ERR_LOCKED);
327
334
err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
329
336
TEST_CARD_REMOVAL (ctrl, err);
330
return map_to_assuan_status (err);
408
415
rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
410
return map_to_assuan_status (rc);
412
419
rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
415
return ASSUAN_Out_Of_Core;
422
return out_of_core ();
417
424
assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
418
425
free (serial_and_stamp);
505
512
rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
507
return map_to_assuan_status (rc);
508
515
rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
511
return ASSUAN_Out_Of_Core;
518
return out_of_core ();
513
520
assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
522
529
free (serial_and_stamp);
523
return ASSUAN_Out_Of_Core;
530
return out_of_core ();
526
533
rc = assuan_inquire (ctx, command, NULL, NULL, 0);
527
534
free (command); /* (must use standard free here) */
530
if (rc != ASSUAN_Canceled)
537
if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
531
538
log_error ("inquire KNOWNCARDP failed: %s\n",
532
assuan_strerror (rc));
533
540
free (serial_and_stamp);
614
621
{ /* Yeah, got that key - send it back. */
615
622
rc = assuan_send_data (ctx, pk, pklen);
617
rc = map_assuan_err (rc);
656
662
n = gcry_sexp_canon_len (p, 0, NULL, NULL);
657
663
rc = assuan_send_data (ctx, p, n);
658
rc = map_assuan_err (rc);
688
693
for (p=line,n=0; hexdigitp (p); p++, n++)
691
return set_error (Parameter_Error, "invalid hexstring");
696
return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
693
return set_error (Parameter_Error, "no data given");
698
return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
695
return set_error (Parameter_Error, "odd number of digits");
700
return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
697
702
buf = xtrymalloc (n);
699
return ASSUAN_Out_Of_Core;
704
return out_of_core ();
701
706
ctrl->in_data.value = buf;
702
707
ctrl->in_data.valuelen = n;
728
733
rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
731
return map_assuan_err (rc);
733
738
if (!valuelen || value[valuelen-1])
765
770
else if (!strstr (line, "--"))
766
771
hash_algo = GCRY_MD_SHA1;
768
return set_error (Parameter_Error, "invalid hash algorithm");
773
return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
769
774
/* Skip over options. */
770
775
while ( *line == '-' && line[1] == '-' )
786
791
overwriting the original line with the keyid */
787
792
keyidstr = xtrystrdup (line);
789
return ASSUAN_Out_Of_Core;
794
return out_of_core ();
791
796
rc = app_sign (ctrl->app_ctx,
792
797
keyidstr, hash_algo,
837
842
overwriting the original line with the keyid */
838
843
keyidstr = xtrystrdup (line);
840
return ASSUAN_Out_Of_Core;
845
return out_of_core ();
842
847
rc = app_auth (ctrl->app_ctx,
937
942
/* (We ignore any garbage for now.) */
939
/* FIXME: Applications should not return sensistive data if the card
944
/* FIXME: Applications should not return sensitive data if the card
941
946
rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
943
948
TEST_CARD_REMOVAL (ctrl, rc);
944
return map_to_assuan_status (rc);
977
982
context and thus reuses the Assuan provided LINE. */
978
983
line = linebuf = xtrystrdup (orig_line);
980
return ASSUAN_Out_Of_Core;
985
return out_of_core ();
983
988
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1048
1053
keyid = xtrystrdup (keyid);
1050
return ASSUAN_Out_Of_Core;
1055
return out_of_core ();
1052
1057
/* Now get the actual keydata. */
1053
1058
rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1123
1128
keyno = xtrystrdup (keyno);
1125
return ASSUAN_Out_Of_Core;
1130
return out_of_core ();
1126
1131
rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, pin_cb, ctx);
1129
1134
TEST_CARD_REMOVAL (ctrl, rc);
1130
return map_to_assuan_status (rc);
1146
1151
unsigned char *buffer;
1149
return set_error (Parameter_Error, "number of requested bytes missing");
1154
return set_error (GPG_ERR_ASS_PARAMETER, "number of requested bytes missing");
1150
1155
nbytes = strtoul (line, NULL, 0);
1152
1157
if ((rc = open_card (ctrl, NULL)))
1212
1217
chvnostr = xtrystrdup (chvnostr);
1214
return ASSUAN_Out_Of_Core;
1219
return out_of_core ();
1215
1220
rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, reset_mode, pin_cb, ctx);
1217
1222
log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1218
1223
xfree (chvnostr);
1220
1225
TEST_CARD_REMOVAL (ctrl, rc);
1221
return map_to_assuan_status (rc);
1262
1267
overwriting the original line with the keyid. */
1263
1268
keyidstr = xtrystrdup (line);
1265
return ASSUAN_Out_Of_Core;
1270
return out_of_core ();
1267
1272
rc = app_check_pin (ctrl->app_ctx,
1352
1357
Supported values of WHAT are:
1354
1359
socket_name - Return the name of the socket.
1360
status - Return the status of the current slot (in the future, may
1361
also return the status of all slots). The status is a list of
1362
one-character flags. The following flags are currently defined:
1363
'u' Usable card present. This is the normal state during operation.
1364
'r' Card removed. A reset is necessary.
1365
These flags are exclusive.
1370
1380
rc = gpg_error (GPG_ERR_NO_DATA);
1382
else if (!strcmp (line, "status"))
1384
ctrl_t ctrl = assuan_get_pointer (ctx);
1385
int slot = ctrl->reader_slot;
1388
if (!ctrl->server_local->card_removed && slot != -1)
1390
struct slot_status_s *ss;
1392
if (!(slot >= 0 && slot < DIM(slot_table)))
1395
ss = &slot_table[slot];
1400
if (ss->any && (ss->status & 1))
1403
rc = assuan_send_data (ctx, &flag, 1);
1373
rc = set_error (Parameter_Error, "unknown value for WHAT");
1406
rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1575
rc = assuan_init_connected_socket_server (&ctx, fd);
1606
rc = assuan_init_socket_server_ext (&ctx, fd, 2);
1579
1610
log_error ("failed to initialize the server: %s\n",
1580
assuan_strerror(rc));
1583
1614
rc = register_commands (ctx);
1586
1617
log_error ("failed to register commands with Assuan: %s\n",
1587
assuan_strerror(rc));
1590
1621
assuan_set_pointer (ctx, &ctrl);
1620
log_info ("Assuan accept problem: %s\n", assuan_strerror (rc));
1651
log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1624
1655
rc = assuan_process (ctx);
1627
log_info ("Assuan processing failed: %s\n", assuan_strerror (rc));
1658
log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1732
1763
log_info ("updating status of slot %d to 0x%04X\n",
1733
1764
ss->slot, status);
1766
/* FIXME: Should this be IDX instead of ss->slot? This
1767
depends on how client sessions will associate the reader
1768
status with their session. */
1735
1769
sprintf (templ, "reader_%d.status", ss->slot);
1736
1770
fname = make_filename (opt.homedir, templ, NULL );
1737
1771
fp = fopen (fname, "w");
1782
/* If a status script is executable, run it. */
1784
const char *args[9], *envs[2];
1785
char numbuf1[30], numbuf2[30], numbuf3[30];
1786
char *homestr, *envstr;
1789
homestr = make_filename (opt.homedir, NULL);
1790
if (asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
1791
log_error ("out of core while building environment\n");
1797
sprintf (numbuf1, "%d", ss->slot);
1798
sprintf (numbuf2, "0x%04X", ss->status);
1799
sprintf (numbuf3, "0x%04X", status);
1800
args[0] = "--reader-port";
1802
args[2] = "--old-code";
1804
args[4] = "--new-code";
1806
args[6] = "--status";
1807
args[7] = ((status & 1)? "USABLE":
1808
(status & 4)? "ACTIVE":
1809
(status & 2)? "PRESENT": "NOCARD");
1812
fname = make_filename (opt.homedir, "scd-event", NULL);
1813
err = gnupg_spawn_process_detached (fname, args, envs);
1814
if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
1815
log_error ("failed to run event handler `%s': %s\n",
1816
fname, gpg_strerror (err));
1748
1823
/* Set the card removed flag for all current sessions. We
1749
1824
will set this on any card change because a reset or
1750
1825
SERIALNO request must be done in any case. */
1752
update_card_removed (ss->slot, 1);
1827
update_card_removed (idx, 1);
1755
1830
ss->status = status;