+
+
+//
+// Software token support
+//
+void PCSCMonitor::startSoftTokens()
+{
+ // clear all software readers. This will kill the respective TokenDaemons
+ clearReaders(Reader::software);
+
+ // scan for new ones
+ CodeRepository<Bundle> candidates("Security/tokend", ".tokend", "TOKENDAEMONPATH", false);
+ candidates.update();
+ for (CodeRepository<Bundle>::iterator it = candidates.begin(); it != candidates.end(); ++it) {
+ if (CFTypeRef type = (*it)->infoPlistItem("TokendType"))
+ if (CFEqual(type, CFSTR("software")))
+ loadSoftToken(*it);
+ }
+}
+
+void PCSCMonitor::loadSoftToken(Bundle *tokendBundle)
+{
+ try {
+ string bundleName = tokendBundle->identifier();
+
+ // prepare a virtual reader, removing any existing one (this would kill a previous tokend)
+ assert(mReaders.find(bundleName) == mReaders.end()); // not already present
+ RefPointer<Reader> reader = new Reader(tokenCache(), bundleName);
+
+ // now launch the tokend
+ RefPointer<TokenDaemon> tokend = new TokenDaemon(tokendBundle,
+ reader->name(), reader->pcscState(), reader->cache);
+
+ if (tokend->state() == ServerChild::dead) { // ah well, this one's no good
+ secdebug("pcsc", "softtoken %s tokend launch failed", bundleName.c_str());
+ Syslog::notice("Software token %s failed to run", tokendBundle->canonicalPath().c_str());
+ return;
+ }
+
+ // probe the (single) tokend
+ if (!tokend->probe()) { // non comprende...
+ secdebug("pcsc", "softtoken %s probe failed", bundleName.c_str());
+ Syslog::notice("Software token %s refused operation", tokendBundle->canonicalPath().c_str());
+ return;
+ }
+
+ // okay, this seems to work. Set it up
+ mReaders.insert(make_pair(reader->name(), reader));
+ reader->insertToken(tokend);
+ Syslog::notice("Software token %s activated", bundleName.c_str());
+ } catch (...) {
+ secdebug("pcsc", "exception loading softtoken %s - continuing", tokendBundle->identifier().c_str());
+ }
+}