Ejemplo n.º 1
0
  public static void main(String[] argv) throws Exception {
    OptionSet args = parseOptions(argv);

    if (args.has(OPT_VERBOSE)) {
      verbose = true;
      // Set up slf4j simple in a way that pleases us
      System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "debug");
      System.setProperty("org.slf4j.simpleLogger.showThreadName", "true");
      System.setProperty("org.slf4j.simpleLogger.showShortLogName", "true");
      System.setProperty("org.slf4j.simpleLogger.levelInBrackets", "true");
    } else {
      System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "warn");
    }

    if (args.has(OPT_VERSION)) {
      String version = "apdu4j " + getVersion(SCTool.class);
      // Append host information
      version += "\nRunning on " + System.getProperty("os.name");
      version += " " + System.getProperty("os.version");
      version += " " + System.getProperty("os.arch");
      version += ", Java " + System.getProperty("java.version");
      version += " by " + System.getProperty("java.vendor");
      System.out.println(version);
    }
    if (args.has(OPT_TEST_SERVER)) {
      // TODO: have the possibility to run SocketServer as well?
      RemoteTerminalServer srv = new RemoteTerminalServer(TestServer.class);
      srv.start(string2socket((String) args.valueOf(OPT_TEST_SERVER)));
      System.console().readLine("Press enter to stop\n");
      srv.stop(1);
      System.exit(0);
    }

    // List TerminalFactory providers
    if (args.has(OPT_PROVIDERS)) {
      Provider providers[] = Security.getProviders("TerminalFactory.PC/SC");
      if (providers != null) {
        System.out.println("Existing TerminalFactory providers:");
        for (Provider p : providers) {
          System.out.println(p.getName());
        }
      }
    }

    // Fix properties on non-windows platforms
    TerminalManager.fixPlatformPaths();

    // Only applies to SunPCSC
    if (args.has(OPT_NO_GET_RESPONSE)) {
      System.setProperty("sun.security.smartcardio.t0GetResponse", "false");
      System.setProperty("sun.security.smartcardio.t1GetResponse", "false");
    }

    // Override PC/SC library path
    if (args.has(OPT_LIB)) {
      System.setProperty("sun.security.smartcardio.library", (String) args.valueOf(OPT_LIB));
    }

    TerminalFactory tf = null;
    CardTerminals terminals = null;

    try {
      // Get a terminal factory
      if (args.has(OPT_PROVIDER)) {
        String pn = (String) args.valueOf(OPT_PROVIDER);
        String pt = (String) args.valueOf(OPT_PROVIDER_TYPE);
        tf = loadFactory(pn, pt);
      } else if (args.has(OPT_SUN)) {
        tf = loadFactory(SUN_CLASS, null);
      } else if (args.has(OPT_JNA)) {
        tf = loadFactory(JNA_CLASS, null);
      } else {
        tf = TerminalFactory.getDefault();
      }

      if (verbose) {
        System.out.println(
            "# Using " + tf.getProvider().getClass().getCanonicalName() + " - " + tf.getProvider());
        if (System.getProperty(TerminalManager.lib_prop) != null) {
          System.out.println(
              "# " + TerminalManager.lib_prop + "=" + System.getProperty(TerminalManager.lib_prop));
        }
      }
      // Get all terminals
      terminals = tf.terminals();
    } catch (Exception e) {
      // XXX: we catch generic Exception here to avoid importing JNA.
      // Try to get a meaningful message
      String msg = TerminalManager.getExceptionMessage(e);
      if (msg == null) msg = e.getMessage();
      System.out.println("No readers: " + msg);
      System.exit(1);
    }

    // Terminals to work on
    List<CardTerminal> do_readers = new ArrayList<CardTerminal>();

    try {
      // List Terminals
      if (args.has(CMD_LIST)) {
        List<CardTerminal> terms = terminals.list();
        if (verbose) {
          System.out.println(
              "# Found " + terms.size() + " terminal" + (terms.size() == 1 ? "" : "s"));
        }
        if (terms.size() == 0) {
          System.err.println("No readers found");
          System.exit(1);
        }
        for (CardTerminal t : terms) {
          String vmd = " ";
          try (PinPadTerminal pp = new PinPadTerminal(t)) {
            pp.probe();
            // Verify, Modify, Display
            if (verbose) {
              vmd += "[";
              vmd += pp.canVerify() ? "V" : " ";
              vmd += pp.canModify() ? "M" : " ";
              vmd += pp.hasDisplay() ? "D" : " ";
              vmd += "] ";
            }
          } catch (CardException e) {
            if (verbose) {
              System.err.println("Could not probe PinPad: " + e.getMessage());
            }
          }

          System.out.println((t.isCardPresent() ? "[*]" : "[ ]") + vmd + t.getName());

          if (args.has(OPT_VERBOSE) && t.isCardPresent()) {
            Card c = t.connect("DIRECT");
            String atr = HexUtils.encodeHexString(c.getATR().getBytes()).toUpperCase();
            c.disconnect(false);
            System.out.println("          " + atr);
            if (args.has(OPT_WEB)) {
              String url = "http://smartcard-atr.appspot.com/parse?ATR=" + atr;
              if (Desktop.isDesktopSupported()) {
                Desktop.getDesktop().browse(new URI(url + "&from=apdu4j"));
              } else {
                System.out.println("          " + url);
              }
            }
          }
        }
      }

      // Select terminals to work on
      if (args.has(OPT_READER)) {
        String reader = (String) args.valueOf(OPT_READER);
        CardTerminal t = terminals.getTerminal(reader);
        if (t == null) {
          System.err.println("Reader \"" + reader + "\" not found.");
          System.exit(1);
        }
        do_readers = Arrays.asList(t);
      } else {
        do_readers = terminals.list(State.CARD_PRESENT);
        if (do_readers.size() > 1 && !args.hasArgument(OPT_ALL)) {
          System.err.println("More than one reader with a card found.");
          System.err.println("Run with --" + OPT_ALL + " to work with all found cards");
          System.exit(1);
        } else if (do_readers.size() == 0 && !args.has(CMD_LIST)) {
          // But if there is a single reader, wait for a card insertion
          List<CardTerminal> empty = terminals.list(State.CARD_ABSENT);
          if (empty.size() == 1 && args.has(OPT_WAIT)) {
            CardTerminal rdr = empty.get(0);
            System.out.println("Please enter a card into " + rdr.getName());
            if (!empty.get(0).waitForCardPresent(30000)) {
              System.out.println("Timeout.");
            } else {
              do_readers = Arrays.asList(rdr);
            }
          } else {
            System.err.println("No reader with a card found!");
            System.exit(1);
          }
        }
      }

    } catch (CardException e) {
      System.out.println("Could not list readers: " + TerminalManager.getExceptionMessage(e));
      e.printStackTrace();
    }

    for (CardTerminal t : do_readers) {
      work(t, args);
    }
  }