~ubuntu-branches/ubuntu/feisty/gnupg2/feisty

« back to all changes in this revision

Viewing changes to scd/command.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2006-11-24 18:48:23 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20061124184823-17ir9m46tl09n9k4
Tags: 2.0.0-4ubuntu1
* Synchronize to Debian, reapply remaining Ubuntu changes to pristine Debian
  version:
  - Remove libpcsclite-dev, libopensc2-dev build dependencies (they are in
    universe).

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include <ksba.h>
38
38
#include "app-common.h"
39
39
#include "apdu.h" /* Required for apdu_*_reader (). */
 
40
#include "exechelp.h"
40
41
 
41
42
/* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
42
43
#define MAXLEN_PIN 100
45
46
#define MAXLEN_KEYDATA 4096
46
47
 
47
48
 
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))
49
50
 
50
51
 
51
52
/* Macro to flag a removed card.  */
104
105
};
105
106
 
106
107
 
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];
109
112
 
110
113
 
212
215
          slot_table[slot].reset_failed = 1;
213
216
        }
214
217
    }
215
 
  ctrl->reader_slot = -1;
216
218
 
217
219
  /* If we hold a lock, unlock now. */
218
220
  if (locked_session && ctrl->server_local == locked_session)
229
231
  if (!pth_mutex_acquire (&status_file_update_lock, 0, NULL))
230
232
    {
231
233
      log_error ("failed to acquire status_fle_update lock\n");
 
234
      ctrl->reader_slot = -1;
232
235
      return;
233
236
    }
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");
 
241
 
 
242
  /* Do this last, so that update_card_removed does its job.  */
 
243
  ctrl->reader_slot = -1;
238
244
}
239
245
 
240
246
 
257
263
      /* A value of 0 is allowed to reset the event signal. */
258
264
      int i = *value? atoi (value) : -1;
259
265
      if (i < 0)
260
 
        return ASSUAN_Parameter_Error;
 
266
        return gpg_error (GPG_ERR_ASS_PARAMETER);
261
267
      ctrl->server_local->event_signal = i;
262
268
    }
263
269
 
287
293
  if (ss->slot == -1)
288
294
    ss->slot = apdu_open_reader (opt.reader_port);
289
295
 
290
 
  return ss->slot;
 
296
  /* Return the slot_table index.  */
 
297
  return 0;
291
298
}
292
299
 
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
295
 
   time */
 
302
   time.  */
296
303
static assuan_error_t
297
304
open_card (ctrl_t ctrl, const char *apptype)
298
305
{
303
310
     the SERIALNO command and a reset are able to clear from that
304
311
     state. */
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);
307
314
 
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);
328
335
 
329
336
  TEST_CARD_REMOVAL (ctrl, err);
330
 
  return map_to_assuan_status (err);
 
337
  return err;
331
338
}
332
339
 
333
340
 
407
414
 
408
415
  rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
409
416
  if (rc)
410
 
    return map_to_assuan_status (rc);
 
417
    return rc;
411
418
 
412
419
  rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
413
420
  xfree (serial);
414
421
  if (rc < 0)
415
 
    return ASSUAN_Out_Of_Core;
 
422
    return out_of_core ();
416
423
  rc = 0;
417
424
  assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
418
425
  free (serial_and_stamp);
504
511
 
505
512
    rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
506
513
    if (rc)
507
 
      return map_to_assuan_status (rc);
 
514
      return rc;
508
515
    rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
509
516
    xfree (serial);
510
517
    if (rc < 0)
511
 
      return ASSUAN_Out_Of_Core;
 
518
      return out_of_core ();
512
519
    rc = 0;
513
520
    assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
514
521
 
520
527
        if (rc < 0)
521
528
          {
522
529
            free (serial_and_stamp);
523
 
            return ASSUAN_Out_Of_Core;
 
530
            return out_of_core ();
524
531
          }
525
532
        rc = 0;
526
533
        rc = assuan_inquire (ctx, command, NULL, NULL, 0); 
527
534
        free (command);  /* (must use standard free here) */
528
535
        if (rc)
529
536
          {
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));
 
539
                         gpg_strerror (rc));
533
540
            free (serial_and_stamp);
534
541
            return rc; 
535
542
          }
544
551
    rc = app_write_learn_status (ctrl->app_ctx, ctrl);
545
552
 
546
553
  TEST_CARD_REMOVAL (ctrl, rc);
547
 
  return map_to_assuan_status (rc);
 
554
  return rc;
548
555
}
549
556
 
550
557
 
579
586
    }
580
587
 
581
588
  TEST_CARD_REMOVAL (ctrl, rc);
582
 
  return map_to_assuan_status (rc);
 
589
  return rc;
583
590
}
584
591
 
585
592
 
614
621
    { /* Yeah, got that key - send it back.  */
615
622
      rc = assuan_send_data (ctx, pk, pklen);
616
623
      xfree (pk);
617
 
      rc = map_assuan_err (rc);
618
624
      xfree (line);
619
625
      line = NULL;
620
626
      goto leave;
655
661
 
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);
659
664
  xfree (p);
660
665
 
661
666
 
663
668
  ksba_cert_release (kc);
664
669
  xfree (cert);
665
670
  TEST_CARD_REMOVAL (ctrl, rc);
666
 
  return map_to_assuan_status (rc);
 
671
  return rc;
667
672
}
668
673
 
669
674
 
688
693
  for (p=line,n=0; hexdigitp (p); p++, n++)
689
694
    ;
690
695
  if (*p)
691
 
    return set_error (Parameter_Error, "invalid hexstring");
 
696
    return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
692
697
  if (!n)
693
 
    return set_error (Parameter_Error, "no data given");
 
698
    return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
694
699
  if ((n&1))
695
 
    return set_error (Parameter_Error, "odd number of digits");
 
700
    return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
696
701
  n /= 2;
697
702
  buf = xtrymalloc (n);
698
703
  if (!buf)
699
 
    return ASSUAN_Out_Of_Core;
 
704
    return out_of_core ();
700
705
 
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); 
729
734
  free (command);  
730
735
  if (rc)
731
 
    return map_assuan_err (rc);
 
736
    return rc;
732
737
 
733
738
  if (!valuelen || value[valuelen-1])
734
739
    {
765
770
  else if (!strstr (line, "--"))
766
771
    hash_algo = GCRY_MD_SHA1; 
767
772
  else
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] == '-' )
771
776
    {
786
791
     overwriting the original line with the keyid */
787
792
  keyidstr = xtrystrdup (line);
788
793
  if (!keyidstr)
789
 
    return ASSUAN_Out_Of_Core;
 
794
    return out_of_core ();
790
795
  
791
796
  rc = app_sign (ctrl->app_ctx,
792
797
                 keyidstr, hash_algo,
808
813
    }
809
814
 
810
815
  TEST_CARD_REMOVAL (ctrl, rc);
811
 
  return map_to_assuan_status (rc);
 
816
  return rc;
812
817
}
813
818
 
814
819
/* PKAUTH <hexified_id>
837
842
     overwriting the original line with the keyid */
838
843
  keyidstr = xtrystrdup (line);
839
844
  if (!keyidstr)
840
 
    return ASSUAN_Out_Of_Core;
 
845
    return out_of_core ();
841
846
  
842
847
  rc = app_auth (ctrl->app_ctx,
843
848
                 keyidstr,
858
863
    }
859
864
 
860
865
  TEST_CARD_REMOVAL (ctrl, rc);
861
 
  return map_to_assuan_status (rc);
 
866
  return rc;
862
867
}
863
868
 
864
869
/* PKDECRYPT <hexified_id>
881
886
 
882
887
  keyidstr = xtrystrdup (line);
883
888
  if (!keyidstr)
884
 
    return ASSUAN_Out_Of_Core;
 
889
    return out_of_core ();
885
890
  rc = app_decipher (ctrl->app_ctx,
886
891
                     keyidstr, 
887
892
                     pin_cb, ctx,
902
907
    }
903
908
 
904
909
  TEST_CARD_REMOVAL (ctrl, rc);
905
 
  return map_to_assuan_status (rc);
 
910
  return rc;
906
911
}
907
912
 
908
913
 
936
941
 
937
942
  /* (We ignore any garbage for now.) */
938
943
 
939
 
  /* FIXME: Applications should not return sensistive data if the card
 
944
  /* FIXME: Applications should not return sensitive data if the card
940
945
     is locked.  */
941
946
  rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
942
947
 
943
948
  TEST_CARD_REMOVAL (ctrl, rc);
944
 
  return map_to_assuan_status (rc);
 
949
  return rc;
945
950
}
946
951
 
947
952
 
977
982
     context and thus reuses the Assuan provided LINE. */
978
983
  line = linebuf = xtrystrdup (orig_line);
979
984
  if (!line)
980
 
    return ASSUAN_Out_Of_Core;
 
985
    return out_of_core ();
981
986
 
982
987
  keyword = line;
983
988
  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
993
998
  xfree (linebuf);
994
999
 
995
1000
  TEST_CARD_REMOVAL (ctrl, rc);
996
 
  return map_to_assuan_status (rc);
 
1001
  return rc;
997
1002
}
998
1003
 
999
1004
 
1033
1038
        line++;
1034
1039
    }
1035
1040
  if (!*line)
1036
 
    return set_error (Parameter_Error, "no keyid given");
 
1041
    return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1037
1042
  keyid = line;
1038
1043
  while (*line && !spacep (line))
1039
1044
    line++;
1047
1052
 
1048
1053
  keyid = xtrystrdup (keyid);
1049
1054
  if (!keyid)
1050
 
    return ASSUAN_Out_Of_Core;
 
1055
    return out_of_core ();
1051
1056
 
1052
1057
  /* Now get the actual keydata. */
1053
1058
  rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1064
1069
  xfree (keydata);
1065
1070
 
1066
1071
  TEST_CARD_REMOVAL (ctrl, rc);
1067
 
  return map_to_assuan_status (rc);
 
1072
  return rc;
1068
1073
}
1069
1074
 
1070
1075
 
1108
1113
        line++;
1109
1114
    }
1110
1115
  if (!*line)
1111
 
    return set_error (Parameter_Error, "no key number given");
 
1116
    return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1112
1117
  keyno = line;
1113
1118
  while (*line && !spacep (line))
1114
1119
    line++;
1122
1127
 
1123
1128
  keyno = xtrystrdup (keyno);
1124
1129
  if (!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);
1127
1132
  xfree (keyno);
1128
1133
 
1129
1134
  TEST_CARD_REMOVAL (ctrl, rc);
1130
 
  return map_to_assuan_status (rc);
 
1135
  return rc;
1131
1136
}
1132
1137
 
1133
1138
 
1146
1151
  unsigned char *buffer;
1147
1152
 
1148
1153
  if (!*line)
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);
1151
1156
 
1152
1157
  if ((rc = open_card (ctrl, NULL)))
1157
1162
 
1158
1163
  buffer = xtrymalloc (nbytes);
1159
1164
  if (!buffer)
1160
 
    return ASSUAN_Out_Of_Core;
 
1165
    return out_of_core ();
1161
1166
 
1162
1167
  rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
1163
1168
  if (!rc)
1169
1174
  xfree (buffer);
1170
1175
 
1171
1176
  TEST_CARD_REMOVAL (ctrl, rc);
1172
 
  return map_to_assuan_status (rc);
 
1177
  return rc;
1173
1178
}
1174
1179
 
1175
1180
 
1197
1202
        line++;
1198
1203
    }
1199
1204
  if (!*line)
1200
 
    return set_error (Parameter_Error, "no CHV number given");
 
1205
    return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1201
1206
  chvnostr = line;
1202
1207
  while (*line && !spacep (line))
1203
1208
    line++;
1211
1216
  
1212
1217
  chvnostr = xtrystrdup (chvnostr);
1213
1218
  if (!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);
1216
1221
  if (rc)
1217
1222
    log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1218
1223
  xfree (chvnostr);
1219
1224
 
1220
1225
  TEST_CARD_REMOVAL (ctrl, rc);
1221
 
  return map_to_assuan_status (rc);
 
1226
  return rc;
1222
1227
}
1223
1228
 
1224
1229
 
1262
1267
     overwriting the original line with the keyid. */
1263
1268
  keyidstr = xtrystrdup (line);
1264
1269
  if (!keyidstr)
1265
 
    return ASSUAN_Out_Of_Core;
 
1270
    return out_of_core ();
1266
1271
  
1267
1272
  rc = app_check_pin (ctrl->app_ctx,
1268
1273
                      keyidstr,
1272
1277
    log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1273
1278
 
1274
1279
  TEST_CARD_REMOVAL (ctrl, rc);
1275
 
  return map_to_assuan_status (rc);
 
1280
  return rc;
1276
1281
}
1277
1282
 
1278
1283
 
1316
1321
  
1317
1322
  if (rc)
1318
1323
    log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1319
 
  return map_to_assuan_status (rc);
 
1324
  return rc;
1320
1325
}
1321
1326
 
1322
1327
 
1342
1347
 
1343
1348
  if (rc)
1344
1349
    log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1345
 
  return map_to_assuan_status (rc);
 
1350
  return rc;
1346
1351
}
1347
1352
 
1348
1353
 
1352
1357
   Supported values of WHAT are:
1353
1358
 
1354
1359
   socket_name - Return the name of the socket.
1355
 
 
 
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.
1356
1366
*/
1357
1367
 
1358
1368
static int
1369
1379
      else
1370
1380
        rc = gpg_error (GPG_ERR_NO_DATA);
1371
1381
    }
 
1382
  else if (!strcmp (line, "status"))
 
1383
    {
 
1384
      ctrl_t ctrl = assuan_get_pointer (ctx);
 
1385
      int slot = ctrl->reader_slot;
 
1386
      char flag = 'r';
 
1387
 
 
1388
      if (!ctrl->server_local->card_removed && slot != -1)
 
1389
        {
 
1390
          struct slot_status_s *ss;
 
1391
          
 
1392
          if (!(slot >= 0 && slot < DIM(slot_table)))
 
1393
            BUG ();
 
1394
 
 
1395
          ss = &slot_table[slot];
 
1396
 
 
1397
          if (!ss->valid)
 
1398
            BUG ();
 
1399
 
 
1400
          if (ss->any && (ss->status & 1))
 
1401
            flag = 'u';
 
1402
        }
 
1403
      rc = assuan_send_data (ctx, &flag, 1);
 
1404
    }
1372
1405
  else
1373
 
    rc = set_error (Parameter_Error, "unknown value for WHAT");
 
1406
    rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1374
1407
  return rc;
1375
1408
}
1376
1409
 
1426
1459
{
1427
1460
  ctrl_t ctrl = assuan_get_pointer (ctx);
1428
1461
  int rc;
1429
 
  int rc_is_assuan = 0;
1430
1462
  unsigned char *apdu;
1431
1463
  size_t apdulen;
1432
1464
  int with_atr;
1472
1504
  apdu = hex_to_buffer (line, &apdulen);
1473
1505
  if (!apdu)
1474
1506
    {
1475
 
      rc = gpg_error_from_errno (errno);
 
1507
      rc = gpg_error_from_syserror ();
1476
1508
      goto leave;
1477
1509
    }
1478
1510
  if (apdulen)
1486
1518
        log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1487
1519
      else
1488
1520
        {
1489
 
          rc_is_assuan = 1;
1490
1521
          rc = assuan_send_data (ctx, result, resultlen);
1491
1522
          xfree (result);
1492
1523
        }
1495
1526
 
1496
1527
 leave:
1497
1528
  TEST_CARD_REMOVAL (ctrl, rc);
1498
 
  return rc_is_assuan? rc : map_to_assuan_status (rc);
 
1529
  return rc;
1499
1530
}
1500
1531
 
1501
1532
 
1572
1603
    }
1573
1604
  else
1574
1605
    {
1575
 
      rc = assuan_init_connected_socket_server (&ctx, fd);
 
1606
      rc = assuan_init_socket_server_ext (&ctx, fd, 2);
1576
1607
    }
1577
1608
  if (rc)
1578
1609
    {
1579
1610
      log_error ("failed to initialize the server: %s\n",
1580
 
                 assuan_strerror(rc));
 
1611
                 gpg_strerror(rc));
1581
1612
      scd_exit (2);
1582
1613
    }
1583
1614
  rc = register_commands (ctx);
1584
1615
  if (rc)
1585
1616
    {
1586
1617
      log_error ("failed to register commands with Assuan: %s\n",
1587
 
                 assuan_strerror(rc));
 
1618
                 gpg_strerror(rc));
1588
1619
      scd_exit (2);
1589
1620
    }
1590
1621
  assuan_set_pointer (ctx, &ctrl);
1617
1648
        }
1618
1649
      else if (rc)
1619
1650
        {
1620
 
          log_info ("Assuan accept problem: %s\n", assuan_strerror (rc));
 
1651
          log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1621
1652
          break;
1622
1653
        }
1623
1654
      
1624
1655
      rc = assuan_process (ctx);
1625
1656
      if (rc)
1626
1657
        {
1627
 
          log_info ("Assuan processing failed: %s\n", assuan_strerror (rc));
 
1658
          log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1628
1659
          continue;
1629
1660
        }
1630
1661
    }
1731
1762
 
1732
1763
          log_info ("updating status of slot %d to 0x%04X\n",
1733
1764
                    ss->slot, status);
1734
 
            
 
1765
 
 
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");
1745
1779
            }
1746
1780
          xfree (fname);
1747
1781
            
 
1782
          /* If a status script is executable, run it. */
 
1783
          {
 
1784
            const char *args[9], *envs[2];
 
1785
            char numbuf1[30], numbuf2[30], numbuf3[30];
 
1786
            char *homestr, *envstr;
 
1787
            gpg_error_t err;
 
1788
            
 
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");
 
1792
            else
 
1793
              {
 
1794
                envs[0] = envstr;
 
1795
                envs[1] = NULL;
 
1796
 
 
1797
                sprintf (numbuf1, "%d", ss->slot);
 
1798
                sprintf (numbuf2, "0x%04X", ss->status);
 
1799
                sprintf (numbuf3, "0x%04X", status);
 
1800
                args[0] = "--reader-port";
 
1801
                args[1] = numbuf1; 
 
1802
                args[2] = "--old-code";
 
1803
                args[3] = numbuf2;  
 
1804
                args[4] = "--new-code";
 
1805
                args[5] = numbuf3; 
 
1806
                args[6] = "--status";
 
1807
                args[7] = ((status & 1)? "USABLE":
 
1808
                           (status & 4)? "ACTIVE":
 
1809
                           (status & 2)? "PRESENT": "NOCARD");
 
1810
                args[8] = NULL;  
 
1811
 
 
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));
 
1817
                xfree (fname);
 
1818
                free (envstr);
 
1819
              }
 
1820
            xfree (homestr);
 
1821
          }
 
1822
 
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.  */
1751
1826
          if (ss->any)
1752
 
            update_card_removed (ss->slot, 1);
 
1827
            update_card_removed (idx, 1);
1753
1828
          
1754
1829
          ss->any = 1;
1755
1830
          ss->status = status;
1769
1844
                  kill (pid, signo);
1770
1845
#endif
1771
1846
              }
 
1847
 
1772
1848
        }
1773
1849
    }
1774
1850
}