Exemple #1
0
int
find_slot_by_slotlabel_and_tokenlabel(pkcs11_handle_t *h,
    const char *wanted_slot_label, const char *wanted_token_label,
    unsigned int *slot_num)
{
  SECMODModule *module = h->module;
  PK11SlotInfo *slot;
  unsigned long i;
  int rv;

  if (slot_num == NULL || module == NULL)
    return (-1);

  if (wanted_token_label == NULL){
    rv = find_slot_by_slotlabel(h, wanted_slot_label, slot_num);
    return (rv);
  }

  /* wanted_token_label != NULL */
  if (strcmp(wanted_slot_label, "none") == 0) {
    for (i = 0; i < module->slotCount; i++) {
      if (module->slots[i] && PK11_IsPresent(module->slots[i])) {
	const char *token_label;
	slot = PK11_ReferenceSlot(module->slots[i]);
	token_label = PK11_GetTokenName(slot);
	if (memcmp_pad_max((void *) token_label, strlen(token_label),
	    (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0) {
          h->slot =  slot;
          *slot_num =  PK11_GetSlotID(slot);
	  return (0);
        }
      }
    }
    return (-1);
  } else {
    for (i = 0; i < module->slotCount; i++) {
      if (module->slots[i] && PK11_IsPresent(module->slots[i])) {
	const char *slot_label;
	const char *token_label;

	slot = PK11_ReferenceSlot(module->slots[i]);
	slot_label = PK11_GetSlotName(slot);
	token_label = PK11_GetTokenName(slot);
	if ((memcmp_pad_max((void *)slot_label, strlen(slot_label),
	    (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) &&
            (memcmp_pad_max((void *)token_label, strlen(token_label),
	    (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0))
	{
          h->slot =  slot;
          *slot_num =  PK11_GetSlotID(slot);
	  return (0);
        }
      }
    }
    return (-1);
  }
}
Exemple #2
0
int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot_num)
{
  /* NSS manages the sessions under the covers, use this function to
   * select a slot */
  if (h->slot != NULL) {
    /* we've already selected the slot */
    if (PK11_GetSlotID(h->slot) == slot_num) {
	return 0;
    }
    /* the slot we've selected isn't the one we want to open */
    PK11_FreeSlot(h->slot);
    h->slot = NULL;
  }

  /* look the slot up */
  h->slot = SECMOD_LookupSlot(h->module->moduleID, slot_num);
  if (h->slot == NULL) {
    return -1;
  }

  /* make sure it is present */
  if (!PK11_IsPresent(h->slot)) {
    PK11_FreeSlot(h->slot);
    h->slot = NULL;
    return -1;
  }
  return 0;
}
static void
sync_initial_tokens_from_driver (GsdSmartcardManager *self,
                                 SECMODModule        *driver,
                                 GHashTable          *smartcards,
                                 GCancellable        *cancellable)
{
        GsdSmartcardManagerPrivate *priv = self->priv;
        int i;

        for (i = 0; i < driver->slotCount; i++) {
                PK11SlotInfo *card;

                card = driver->slots[i];

                if (PK11_IsPresent (card)) {
                        CK_SLOT_ID slot_id;
                        slot_id = PK11_GetSlotID (card);

                        g_debug ("Detected smartcard in slot %d at start up", (int) slot_id);

                        g_hash_table_replace (smartcards,
                                              GINT_TO_POINTER ((int) slot_id),
                                              PK11_ReferenceSlot (card));
                        gsd_smartcard_service_sync_token (priv->service, card, cancellable);
                }
        }
}
static PK11SlotInfo *
msd_smartcard_find_slot_from_id (MsdSmartcard *card,
                                 int           slot_id)
{
        int i;

        for (i = 0; i < card->priv->module->slotCount; i++) {
                if (PK11_GetSlotID (card->priv->module->slots[i]) == slot_id) {
                        return card->priv->module->slots[i];
                }
        }

        return NULL;
}
Exemple #5
0
/*
 * find a slot by it's slot number or label. If slot number is '0' any
 * slot is ok.
 */
int find_slot_by_number_and_label(pkcs11_handle_t *h,
				  int wanted_slot_id,
				  const char *wanted_token_label,
                                  unsigned int *slot_num)
{
  int rv;
  const char *token_label = NULL;
  PK11SlotInfo *slot = NULL;

  /* we want a specific slot id, or we don't kare about the label */
  if ((wanted_token_label == NULL) || (wanted_slot_id != 0)) {
    rv = find_slot_by_number(h, wanted_slot_id, slot_num);

    /* if we don't care about the label, or we failed, we're done */
    if ((wanted_token_label == NULL) || (rv != 0)) {
      return rv;
    }

    /* verify it's the label we want */
    token_label = PK11_GetTokenName(h->slot);

    if ((token_label != NULL) &&
        (strcmp (wanted_token_label, token_label) == 0)) {
      return 0;
    }
    return -1;
  }

  /* we want a specific slot by label only */
  slot = PK11_FindSlotByName(wanted_token_label);
  if (!slot) {
    return -1;
  }

  /* make sure it's in the right module */
  if (h->module) {
    if (h->module != PK11_GetModule(slot)) {
	PK11_FreeSlot(slot);
	return -1;
    }
  } else {
    /* no module was specified, use the one slot came in */
    h->module = SECMOD_ReferenceModule(PK11_GetModule(slot));
  }
  h->slot = slot; /* Adopt the reference */
  *slot_num = PK11_GetSlotID(h->slot);
  return 0;
}
static void
msd_smartcard_set_name (MsdSmartcard *card,
                        const char   *name)
{
        if (name == NULL) {
                return;
        }

        if ((card->priv->name == NULL) ||
            (strcmp (card->priv->name, name) != 0)) {
                g_free (card->priv->name);
                card->priv->name = g_strdup (name);

                if (card->priv->slot == NULL) {
                        card->priv->slot = msd_smartcard_find_slot_from_card_name (card,
                                                                                     card->priv->name);

                        if (card->priv->slot != NULL) {
                                int slot_id, slot_series;

                                slot_id = PK11_GetSlotID (card->priv->slot);
                                if (slot_id != card->priv->slot_id) {
                                        msd_smartcard_set_slot_id (card, slot_id);
                                }

                                slot_series = PK11_GetSlotSeries (card->priv->slot);
                                if (slot_series != card->priv->slot_series) {
                                        msd_smartcard_set_slot_series (card, slot_series);
                                }

                                _msd_smartcard_set_state (card, MSD_SMARTCARD_STATE_INSERTED);
                        } else {
                                _msd_smartcard_set_state (card, MSD_SMARTCARD_STATE_REMOVED);
                        }
                }

                g_object_notify (G_OBJECT (card), "name");
        }
}
Exemple #7
0
/*
 * This function will search the slot list to find a slot based on the slot
 * label.  If the wanted_slot_label is "none", then we will return the first
 * slot with the token presented.
 *
 * This function return 0 if it found a matching slot; otherwise, it returns
 * -1.
 */
int
find_slot_by_slotlabel(pkcs11_handle_t *h, const char *wanted_slot_label,
    unsigned int *slotID)
{
  SECMODModule *module = h->module;
  PK11SlotInfo *slot;
  int rv;
  int i;

  if (slotID == NULL || wanted_slot_label == NULL ||
      strlen(wanted_slot_label) == 0 || module == NULL)
    return (-1);

  if (strcmp(wanted_slot_label, "none") == 0) {
    rv = find_slot_by_number(h, 0, slotID);
    return (rv);
  } else {
    /* wanted_slot_label is not "none"  */
    for (i = 0; i < module->slotCount; i++) {
      if (module->slots[i] && PK11_IsPresent(module->slots[i])) {
        const char *slot_label;

	slot = PK11_ReferenceSlot(module->slots[i]);
	slot_label = PK11_GetSlotName(slot);
	if (memcmp_pad_max((void *)slot_label, strlen(slot_label),
	    (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) {
	  h->slot = slot;
	  *slotID = PK11_GetSlotID(slot);
	  return 0;
        }
      }
    }
  }

  return (-1);
}
Exemple #8
0
int find_slot_by_number(pkcs11_handle_t *h, unsigned int slot_num, unsigned int *slotID)
{
  SECMODModule *module = h->module;
  int i;

  /* if module is null,
   * any of the PKCS #11 modules specified in the system config
   * is available, find one */
  if (module == NULL) {
    PK11SlotList *list;
    PK11SlotListElement *le;
    PK11SlotInfo *slot = NULL;

    /* find a slot, we haven't specifically selected a module,
     * so find an appropriate one. */
    /* get them all */
    list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, NULL);
    if (list == NULL) {
	return -1;
    }
    for (le = list->head; le; le = le->next) {
      CK_SLOT_INFO slInfo;
      SECStatus rv;

      slInfo.flags = 0;
      rv = PK11_GetSlotInfo(le->slot, &slInfo);
      if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) {
	slot = PK11_ReferenceSlot(le->slot);
	module = SECMOD_ReferenceModule(PK11_GetModule(le->slot));
	break;
      }
    }
    PK11_FreeSlotList(list);
    if (slot == NULL) {
	return -1;
    }
    h->slot = slot;
    h->module = module;
    *slotID = PK11_GetSlotID(slot);
    return 0;
  }

  /*
   * we're configured with a specific module, look for a present slot
   * on that module. */
  if (slot_num == 0) {
    /* threaded applications should also acquire the
     * DefaultModuleListLock */
    for (i=0; i < module->slotCount; i++) {
      if (module->slots[i] && PK11_IsPresent(module->slots[i])) {
        h->slot = PK11_ReferenceSlot(module->slots[i]);
        *slotID = PK11_GetSlotID(h->slot);
        return 0;
      }
    }
  }
  /* we're configured for a specific module and token, see if it's present */
  slot_num--;
  if (slot_num < module->slotCount && module->slots &&
      module->slots[slot_num] && PK11_IsPresent(module->slots[slot_num])) {
    h->slot = PK11_ReferenceSlot(module->slots[slot_num]);
    *slotID = PK11_GetSlotID(h->slot);
    return 0;
  }
  return -1;
}
static gboolean
watch_one_event_from_driver (GsdSmartcardManager       *self,
                             WatchSmartcardsOperation  *operation,
                             GCancellable              *cancellable,
                             GError                   **error)
{
        GsdSmartcardManagerPrivate *priv = self->priv;
        PK11SlotInfo *card, *old_card;
        CK_SLOT_ID slot_id;
        gulong handler_id;
        int old_slot_series = -1, slot_series;

        handler_id = g_cancellable_connect (cancellable,
                                            G_CALLBACK (on_watch_cancelled),
                                            operation,
                                            NULL);

        card = SECMOD_WaitForAnyTokenEvent (operation->driver, 0, PR_SecondsToInterval (1));

        g_cancellable_disconnect (cancellable, handler_id);

        if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
                g_warning ("smartcard event function cancelled");
                return FALSE;
        }

        if (card == NULL) {
                int error_code;

                error_code = PORT_GetError ();

                operation->number_of_consecutive_errors++;
                if (operation->number_of_consecutive_errors > 10) {
                     g_warning ("Got %d consecutive smartcard errors, so giving up.",
                                operation->number_of_consecutive_errors);

                     g_set_error (error,
                                  GSD_SMARTCARD_MANAGER_ERROR,
                                  GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS,
                                  "encountered unexpected error while "
                                  "waiting for smartcard events (error %x)",
                                  error_code);
                     return FALSE;
                }

                g_warning ("Got potentially spurious smartcard event error: %x.", error_code);

                g_usleep (0.5 * G_USEC_PER_SEC);
                return TRUE;
        }
        operation->number_of_consecutive_errors = 0;

        slot_id = PK11_GetSlotID (card);
        slot_series = PK11_GetSlotSeries (card);

        old_card = g_hash_table_lookup (operation->smartcards, GINT_TO_POINTER ((int) slot_id));

        /* If there is a different card in the slot now than
         * there was before, then we need to emit a removed signal
         * for the old card
         */
        if (old_card != NULL) {
                old_slot_series = PK11_GetSlotSeries (old_card);

                if (old_slot_series != slot_series) {
                        /* Card registered with slot previously is
                         * different than this card, so update its
                         * exported state to track the implicit missed
                         * removal
                         */
                        gsd_smartcard_service_sync_token (priv->service, old_card, cancellable);
                }

                g_hash_table_remove (operation->smartcards, GINT_TO_POINTER ((int) slot_id));
        }

        if (PK11_IsPresent (card)) {
                g_debug ("Detected smartcard insertion event in slot %d", (int) slot_id);

                g_hash_table_replace (operation->smartcards,
                                      GINT_TO_POINTER ((int) slot_id),
                                      PK11_ReferenceSlot (card));

                gsd_smartcard_service_sync_token (priv->service, card, cancellable);
        } else if (old_card == NULL) {
                /* If the just removed smartcard is not known to us then
                 * ignore the removal event. NSS sends a synthentic removal
                 * event for slots that are empty at startup
                 */
                g_debug ("Detected slot %d is empty in reader", (int) slot_id);
        } else {
                g_debug ("Detected smartcard removal event in slot %d", (int) slot_id);

                /* If the just removed smartcard is known to us then
                 * we need to update its exported state to reflect the
                 * removal
                 */
                if (old_slot_series == slot_series)
                        gsd_smartcard_service_sync_token (priv->service, card, cancellable);
        }

        PK11_FreeSlot (card);

        return TRUE;
}
//
// This is the main loop.
//
void SmartCardMonitoringThread::Execute()
{
  PK11SlotInfo *slot;
  const char *tokenName = nsnull;

  //
  // populate token names for already inserted tokens.
  //
  PK11SlotList *sl =
            PK11_FindSlotsByNames(mModule->dllName, nsnull, nsnull, true);
  PK11SlotListElement *sle;
 
  if (sl) {
    for (sle=PK11_GetFirstSafe(sl); sle; 
                                      sle=PK11_GetNextSafe(sl,sle,false)) {
      SetTokenName(PK11_GetSlotID(sle->slot), 
                  PK11_GetTokenName(sle->slot), PK11_GetSlotSeries(sle->slot));
    }
    PK11_FreeSlotList(sl);
  }

  // loop starts..
  do {
    slot = SECMOD_WaitForAnyTokenEvent(mModule, 0, PR_SecondsToInterval(1)  );
    if (slot == nsnull) {
      break;
    }

    // now we have a potential insertion or removal event, see if the slot
    // is present to determine which it is...
    if (PK11_IsPresent(slot)) {
      // insertion
      CK_SLOT_ID slotID = PK11_GetSlotID(slot);
      PRUint32 series = PK11_GetSlotSeries(slot);

      // skip spurious insertion events...
      if (series != GetTokenSeries(slotID)) {
        // if there's a token name, then we have not yet issued a remove
        // event for the previous token, do so now...
        tokenName = GetTokenName(slotID);
        if (tokenName) {
          SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_REMOVE), tokenName);
        }
        tokenName = PK11_GetTokenName(slot);
        // save the token name and series
        SetTokenName(slotID, tokenName, series);
        SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_INSERT), tokenName);
      }
    } else {
      // retrieve token name 
      CK_SLOT_ID slotID = PK11_GetSlotID(slot);
      tokenName = GetTokenName(slotID);
      // if there's not a token name, then the software isn't expecting
      // a (or another) remove event.
      if (tokenName) {
        SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_REMOVE), tokenName);
        // clear the token name (after we send it)
        SetTokenName(slotID, nsnull, 0);
      }
    }
    PK11_FreeSlot(slot);

  } while (1);
}