components/pam_pkcs11/patches/pam_pkcs11.patch
author Shawn Walker-Salas <shawn.walker@oracle.com>
Wed, 30 Mar 2016 13:33:31 -0700
changeset 5682 94c0ca64c022
parent 291 b454e61af367
child 6105 bbe5186e3c04
permissions -rw-r--r--
15558602 TCL_LD_SEARCH_FLAGS is wrongly defined in tclConfig.sh 22228656 remove redundant declarations and additions from makefiles 22252545 simplify build rules for components from common upstream 22378457 tclConfig.sh compiler settings are too specific 22727315 httping curses gui missing 22750630 procmail ignores userland cflags and may use private strstr function 22758725 wdiff uses diff from PATH instead of /usr/gnu/bin/diff 22926847 cloog Makefile typo when setting ASLR_MODE 22935090 tk config script has wrong linker flags

*** pam_pkcs11-0.6.0-ORIG/configure.in	Mon Jun 11 05:17:38 2007
--- pam_pkcs11-WS/configure.in	Mon Sep 28 16:06:48 2009
***************
*** 237,243 ****
  AC_FUNC_REALLOC
  AC_FUNC_STAT
  AC_FUNC_VPRINTF
! AC_CHECK_FUNCS([memset strdup strerror])
  
  
  AC_CONFIG_FILES([ 
--- 237,243 ----
  AC_FUNC_REALLOC
  AC_FUNC_STAT
  AC_FUNC_VPRINTF
! AC_CHECK_FUNCS([memset strdup strerror daemon])
  
  
  AC_CONFIG_FILES([ 
*** pam_pkcs11-0.6.0-ORIG/po/Makefile.in.in	Tue May 22 00:54:56 2007
--- pam_pkcs11-WS/po/Makefile.in.in	Mon Sep 28 16:06:48 2009
***************
*** 46,61 ****
  GMSGFMT_ = @GMSGFMT@
  GMSGFMT_no = @GMSGFMT@
  GMSGFMT_yes = @GMSGFMT_015@
! GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
  MSGFMT_ = @MSGFMT@
  MSGFMT_no = @MSGFMT@
  MSGFMT_yes = @MSGFMT_015@
  MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
! XGETTEXT_ = @XGETTEXT@
  XGETTEXT_no = @XGETTEXT@
  XGETTEXT_yes = @XGETTEXT_015@
  XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
! MSGMERGE = msgmerge
  MSGMERGE_UPDATE = @MSGMERGE@ --update
  MSGINIT = msginit
  MSGCONV = msgconv
--- 46,61 ----
  GMSGFMT_ = @GMSGFMT@
  GMSGFMT_no = @GMSGFMT@
  GMSGFMT_yes = @GMSGFMT_015@
! GMSGFMT = msgfmt
  MSGFMT_ = @MSGFMT@
  MSGFMT_no = @MSGFMT@
  MSGFMT_yes = @MSGFMT_015@
  MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
! XGETTEXT_ = /bin/xgettext
  XGETTEXT_no = @XGETTEXT@
  XGETTEXT_yes = @XGETTEXT_015@
  XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
! MSGMERGE = /usr/lib/intltool/gettext-tools/msgmerge
  MSGMERGE_UPDATE = @MSGMERGE@ --update
  MSGINIT = msginit
  MSGCONV = msgconv
***************
*** 87,94 ****
  .po.gmo:
  	@lang=`echo $* | sed -e 's,.*/,,'`; \
  	test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
! 	echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \
! 	cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
  
  .sin.sed:
  	sed -e '/^#/d' $< > t-$@
--- 87,94 ----
  .po.gmo:
  	@lang=`echo $* | sed -e 's,.*/,,'`; \
  	test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
! 	echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -o $${lang}.gmo $${lang}.po"; \
! 	cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
  
  .sin.sed:
  	sed -e '/^#/d' $< > t-$@
***************
*** 135,145 ****
  	else \
  	  msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \
  	fi; \
! 	$(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
! 	  --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \
! 	  --files-from=$(srcdir)/POTFILES.in \
! 	  --copyright-holder='$(COPYRIGHT_HOLDER)' \
! 	  --msgid-bugs-address="$$msgid_bugs_address"
  	test ! -f $(DOMAIN).po || { \
  	  if test -f $(srcdir)/$(DOMAIN).pot; then \
  	    sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \
--- 135,142 ----
  	else \
  	  msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \
  	fi; \
! 	$(XGETTEXT) -ns -c TRANSLATORS: -m "" -d $(DOMAIN) \
! 	  ../src/pam_pkcs11/pam_pkcs11.c
  	test ! -f $(DOMAIN).po || { \
  	  if test -f $(srcdir)/$(DOMAIN).pot; then \
  	    sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \
*** pam_pkcs11-0.6.0-ORIG/src/common/pkcs11_lib.h	Mon May 21 02:46:19 2007
--- pam_pkcs11-WS/src/common/pkcs11_lib.h	Mon Sep 28 16:06:48 2009
***************
*** 36,46 ****
  PKCS11_EXTERN int find_slot_by_number_and_label(pkcs11_handle_t *h,
                                        int slot_num, const char *slot_label,
                                        unsigned int *slot);
! PKCS11_EXTERN const char *get_slot_label(pkcs11_handle_t *h);
  PKCS11_EXTERN int wait_for_token(pkcs11_handle_t *h,
                                   int wanted_slot_num, 
                                   const char *wanted_slot_label,
                                   unsigned int *slot);
  PKCS11_EXTERN const X509 *get_X509_certificate(cert_object_t *cert);
  PKCS11_EXTERN void release_pkcs11_module(pkcs11_handle_t *h);
  PKCS11_EXTERN int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot);
--- 36,57 ----
  PKCS11_EXTERN int find_slot_by_number_and_label(pkcs11_handle_t *h,
                                        int slot_num, const char *slot_label,
                                        unsigned int *slot);
! PKCS11_EXTERN const char *get_slot_tokenlabel(pkcs11_handle_t *h);
  PKCS11_EXTERN int wait_for_token(pkcs11_handle_t *h,
                                   int wanted_slot_num, 
+                                  const char *wanted_token_label,
+                                  unsigned int *slot);
+ PKCS11_EXTERN int find_slot_by_slotlabel(pkcs11_handle_t *h,
                                   const char *wanted_slot_label,
                                   unsigned int *slot);
+ PKCS11_EXTERN int find_slot_by_slotlabel_and_tokenlabel(pkcs11_handle_t *h,
+                                  const char *wanted_slot_label,
+                                  const char *wanted_token_label,
+                                  unsigned int *slot);
+ PKCS11_EXTERN int wait_for_token_by_slotlabel(pkcs11_handle_t *h,
+                                  const char *wanted_slot_label, 
+                                  const char *wanted_token_label,
+                                  unsigned int *slot);
  PKCS11_EXTERN const X509 *get_X509_certificate(cert_object_t *cert);
  PKCS11_EXTERN void release_pkcs11_module(pkcs11_handle_t *h);
  PKCS11_EXTERN int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot);
*** pam_pkcs11-0.6.0-ORIG/src/common/pkcs11_lib.c	Wed Jun  6 02:33:10 2007
--- pam_pkcs11-WS/src/common/pkcs11_lib.c	Mon Sep 28 16:06:48 2009
***************
*** 67,77 ****
--- 67,138 ----
    return 0;
  }
  
+ /*
+  * memcmp_pad_max() is a specialized version of memcmp() which compares two
+  * pieces of data up to a maximum length.  If the two data match up the
+  * maximum length, they are considered matching.  Trailing blanks do not cause
+  * the match to fail if one of the data is shorted.
+  *
+  * Examples of matches:
+  *	"one"           |
+  *	"one      "     |
+  *	                ^maximum length
+  *
+  *	"Number One     |  X"	(X is beyond maximum length)
+  *	"Number One   " |
+  *	                ^maximum length
+  *
+  * Examples of mismatches:
+  *	" one"
+  *	"one"
+  *
+  *	"Number One    X|"
+  *	"Number One     |"
+  *	                ^maximum length
+  */
+ static int
+ memcmp_pad_max(void *d1, size_t d1_len, void *d2, size_t d2_len,
+     size_t max_sz)
+ {
+ 	size_t		len, extra_len;
+ 	char		*marker;
+ 
+ 	/* No point in comparing anything beyond max_sz */
+ 	if (d1_len > max_sz)
+ 		d1_len = max_sz;
+ 	if (d2_len > max_sz)
+ 		d2_len = max_sz;
+ 
+ 	/* Find shorter of the two data. */
+ 	if (d1_len <= d2_len) {
+ 		len = d1_len;
+ 		extra_len = d2_len;
+ 		marker = d2;
+ 	} else {	/* d1_len > d2_len */
+ 		len = d2_len;
+ 		extra_len = d1_len;
+ 		marker = d1;
+ 	}
+ 
+ 	/* Have a match in the shortest length of data? */
+ 	if (memcmp(d1, d2, len) != 0)
+ 		/* CONSTCOND */
+ 		return (1);
+ 
+ 	/* If the rest of longer data is nulls or blanks, call it a match. */
+ 	while (len < extra_len && marker[len])
+ 		if (!isspace(marker[len++]))
+ 			/* CONSTCOND */
+ 			return (1);
+ 	return (0);
+ }
+ 
  #ifdef HAVE_NSS
  /*
   * Using NSS to find the manage the PKCS #11 modules
   */
  #include "nss.h"
+ #include "nspr.h"
  #include "cert.h"
  #include "secmod.h"
  #include "pk11pub.h"
***************
*** 287,294 ****
    /* we're configured for a specific module and token, see if it's present */
    slot_num--;
    if (slot_num >= 0 && slot_num < module->slotCount && module->slots &&
!       module->slots[i] && PK11_IsPresent(module->slots[i])) {
!     h->slot = PK11_ReferenceSlot(module->slots[i]);
      *slotID = PK11_GetSlotID(h->slot);
      return 0;
    }
--- 348,355 ----
    /* we're configured for a specific module and token, see if it's present */
    slot_num--;
    if (slot_num >= 0 && 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;
    }
***************
*** 301,327 ****
   */
  int find_slot_by_number_and_label(pkcs11_handle_t *h, 
  				  int wanted_slot_id,
! 				  const char *wanted_slot_label,
                                    unsigned int *slot_num)
  {
    int rv;
!   const char *slot_label = NULL;
    PK11SlotInfo *slot = NULL;
  
    /* we want a specific slot id, or we don't kare about the label */
!   if ((wanted_slot_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_slot_label == NULL) || (rv != 0)) {
        return rv;
      }
  
      /* verify it's the label we want */
!     slot_label = PK11_GetTokenName(h->slot);
  
!     if ((slot_label != NULL) && 
!         (strcmp (wanted_slot_label, slot_label) == 0)) {
        return 0;
      }
      return -1;
--- 362,388 ----
   */
  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;
***************
*** 328,334 ****
    }
  
    /* we want a specific slot by label only */
!   slot = PK11_FindSlotByName(wanted_slot_label);
    if (!slot) {
      return -1;
    }
--- 389,395 ----
    }
  
    /* we want a specific slot by label only */
!   slot = PK11_FindSlotByName(wanted_token_label);
    if (!slot) {
      return -1;
    }
***************
*** 350,356 ****
  
  int wait_for_token(pkcs11_handle_t *h, 
                     int wanted_slot_id,
!                    const char *wanted_slot_label,
                     unsigned int *slot_num)
  {
    int rv;
--- 411,417 ----
  
  int wait_for_token(pkcs11_handle_t *h, 
                     int wanted_slot_id,
!                    const char *wanted_token_label,
                     unsigned int *slot_num)
  {
    int rv;
***************
*** 358,364 ****
    rv = -1;
    do {
      /* see if the card we're looking for is inserted */
!     rv = find_slot_by_number_and_label (h, wanted_slot_id,  wanted_slot_label,
                                          slot_num);
      if (rv !=  0) {
        PK11SlotInfo *slot;
--- 419,425 ----
    rv = -1;
    do {
      /* see if the card we're looking for is inserted */
!     rv = find_slot_by_number_and_label (h, wanted_slot_id,  wanted_token_label,
                                          slot_num);
      if (rv !=  0) {
        PK11SlotInfo *slot;
***************
*** 385,390 ****
--- 446,592 ----
    return rv;
  }
  
+ /* 
+  * 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);
+ }
+ 
+ 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);
+   }
+ }
+ 
+ int wait_for_token_by_slotlabel(pkcs11_handle_t *h, 
+                    const char *wanted_slot_label,
+                    const char *wanted_token_label,
+                    unsigned int *slot_num)
+ {
+   int rv;
+ 
+   rv = -1;
+   do {
+     /* see if the card we're looking for is inserted */
+     rv = find_slot_by_slotlabel_and_tokenlabel (h, wanted_slot_label,
+ 	wanted_token_label, slot_num);
+   
+     if (rv !=  0) {
+       PK11SlotInfo *slot;
+       PRIntervalTime slot_poll_interval; /* only for legacy hardware */
+ 
+       /* if the card is not inserted, then block until something happens */
+       slot_poll_interval = PR_MillisecondsToInterval(PAM_PKCS11_POLL_TIME);
+       slot = SECMOD_WaitForAnyTokenEvent(h->module, 0 /* flags */,
+                                          slot_poll_interval);
+ 
+       /* unexpected error */
+       if (slot == NULL) {
+         break;
+       }
+ 
+       /* something happened, continue loop and check if the card
+        * we're looking for is inserted
+        */
+       PK11_FreeSlot(slot);
+       continue;
+     }
+   } while (rv != 0);
+ 
+   return rv;
+ }
+ 
  void release_pkcs11_module(pkcs11_handle_t *h) 
  {
    SECStatus rv;
***************
*** 470,476 ****
    return 0;
  }
  
! const char *get_slot_label(pkcs11_handle_t *h)
  {
    if (!h->slot) {
      return NULL;
--- 672,678 ----
    return 0;
  }
  
! const char *get_slot_tokenlabel(pkcs11_handle_t *h)
  {
    if (!h->slot) {
      return NULL;
***************
*** 613,619 ****
    return (rv == SECSuccess) ? 0 : -1;
  }
  
- #include "nspr.h"
  
  struct tuple_str {
      PRErrorCode	 errNum;
--- 815,820 ----
***************
*** 708,714 ****
  typedef struct {
    CK_SLOT_ID id;
    CK_BBOOL token_present;
!   CK_UTF8CHAR label[33];
  } slot_t;
  
  struct pkcs11_handle_str {
--- 909,916 ----
  typedef struct {
    CK_SLOT_ID id;
    CK_BBOOL token_present;
!   CK_UTF8CHAR label[33]; /* token label */
!   CK_UTF8CHAR slotDescription[64];
  } slot_t;
  
  struct pkcs11_handle_str {
***************
*** 758,764 ****
    DBG3("module permissions: uid = %d, gid = %d, mode = %o",
        module_stat.st_uid, module_stat.st_gid, module_stat.st_mode & 0777);
    if (module_stat.st_mode & S_IWGRP || module_stat.st_mode & S_IWOTH
!       || module_stat.st_uid != 0 || module_stat.st_gid != 0) {
      set_error("the pkcs #11 module MUST be owned by root and MUST NOT "
                "be writeable by the group or others");
      free(h);
--- 960,966 ----
    DBG3("module permissions: uid = %d, gid = %d, mode = %o",
        module_stat.st_uid, module_stat.st_gid, module_stat.st_mode & 0777);
    if (module_stat.st_mode & S_IWGRP || module_stat.st_mode & S_IWOTH
!       || module_stat.st_uid != 0) {
      set_error("the pkcs #11 module MUST be owned by root and MUST NOT "
                "be writeable by the group or others");
      free(h);
***************
*** 807,812 ****
--- 1009,1018 ----
        set_error("C_GetSlotInfo() failed: %x", rv);
        return -1;
      }
+ 
+     (void) memcpy(h->slots[i].slotDescription, sinfo.slotDescription,
+ 		sizeof(h->slots[i].slotDescription));
+ 
      DBG1("- description: %.64s", sinfo.slotDescription);
      DBG1("- manufacturer: %.32s", sinfo.manufacturerID);
      DBG1("- flags: %04lx", sinfo.flags);
***************
*** 945,971 ****
  	
  int find_slot_by_number_and_label(pkcs11_handle_t *h, 
  				  int wanted_slot_id,
! 				  const char *wanted_slot_label,
                                    unsigned int *slot_num)
  {
    unsigned int slot_index;
    int rv;
!   const char *slot_label = NULL;
  
    /* we want a specific slot id, or we don't care about the label */
!   if ((wanted_slot_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_slot_label == NULL) || (rv != 0)) {
        return rv;
      }
  
      /* verify it's the label we want */
!     slot_label = h->slots[*slot_num].label;
  
!     if ((slot_label != NULL) && 
!         (strcmp (wanted_slot_label, slot_label) == 0)) {
        return 0;
      }
      return -1;
--- 1151,1177 ----
  	
  int find_slot_by_number_and_label(pkcs11_handle_t *h, 
  				  int wanted_slot_id,
! 				  const char *wanted_token_label,
                                    unsigned int *slot_num)
  {
    unsigned int slot_index;
    int rv;
!   const char *token_label = NULL;
  
    /* we want a specific slot id, or we don't care 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 = h->slots[*slot_num].label;
  
!     if ((token_label != NULL) && 
!         (strcmp (wanted_token_label, token_label) == 0)) {
        return 0;
      }
      return -1;
***************
*** 974,982 ****
    /* look up the slot by it's label from the list */
    for (slot_index = 0; slot_index < h->slot_count; slot_index++) {
      if (h->slots[slot_index].token_present) {
!       slot_label = h->slots[slot_index].label;
!       if ((slot_label != NULL) && 
!           (strcmp (wanted_slot_label, slot_label) == 0)) {
          *slot_num = slot_index;
          return 0;
        }
--- 1180,1188 ----
    /* look up the slot by it's label from the list */
    for (slot_index = 0; slot_index < h->slot_count; slot_index++) {
      if (h->slots[slot_index].token_present) {
!       token_label = h->slots[slot_index].label;
!       if ((token_label != NULL) && 
!           (strcmp (wanted_token_label, token_label) == 0)) {
          *slot_num = slot_index;
          return 0;
        }
***************
*** 985,993 ****
    return -1;
  }
  
  int wait_for_token(pkcs11_handle_t *h, 
                     int wanted_slot_id,
!                    const char *wanted_slot_label,
                     unsigned int *slot_num)
  {
    int rv;
--- 1191,1310 ----
    return -1;
  }
  
+ /* 
+  * 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 *slot_num)
+ {
+   unsigned long index;
+   size_t len;
+ 
+   if (slot_num == NULL || wanted_slot_label == NULL ||
+       strlen(wanted_slot_label) == 0)
+     return (-1);
+ 
+   if (strcmp(wanted_slot_label, "none") == 0) {
+     for (index = 0; index < h->slot_count; index++) {
+       if (h->slots[index].token_present) {
+ 	*slot_num = index;
+ 	return (0);
+       }
+     }
+   } else {
+     /* Look up the slot by it's slotDescription */
+     len = strlen(wanted_slot_label);
+     for (index = 0; index < h->slot_count; index++) {
+       if (memcmp_pad_max(h->slots[index].slotDescription, 64,
+ 	  (void *)wanted_slot_label, len, 64) == 0) {
+ 	*slot_num = index;
+ 	return (0);
+       }
+     }
+   }
+ 
+   return (-1);
+ }
+ 
+ 
+ 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)
+ {
+   unsigned long i;
+   int rv;
+ 
+   if (slot_num == 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 < h->slot_count; i++) {
+       if (h->slots[i].token_present &&
+ 	  strcmp(wanted_token_label, h->slots[i].label) == 0) {
+ 	*slot_num = i;
+ 	return (0);
+       }
+     }
+     return (-1);
+   } else {
+     for (i = 0; i < h->slot_count; i++) {
+       if (h->slots[i].token_present) {
+         const char *slot_label = h->slots[i].slotDescription;
+         const char *token_label = h->slots[i].label;
+ 
+ 	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))
+         {
+ 	  *slot_num = i;
+ 	  return (0);
+         }
+       }
+     }
+     return (-1);
+   }
+ }
+ 
+ int wait_for_token_by_slotlabel(pkcs11_handle_t *h, 
+                    const char *wanted_slot_label,
+                    const char *wanted_token_label,
+                    unsigned int *slot_num)
+ {
+   int rv;
+ 
+   rv = -1;
+   do {
+     /* see if the card we're looking for is inserted */
+     rv = find_slot_by_slotlabel_and_tokenlabel (h, wanted_slot_label,
+ 	wanted_token_label, slot_num);
+     if (rv !=  0) {
+       /* could call C_WaitForSlotEvent, for now just poll */
+       sleep(10);
+       refresh_slots(h);
+       continue;
+     }
+   } while (rv != 0);
+ 
+   return rv;
+ }
+ 
  int wait_for_token(pkcs11_handle_t *h, 
                     int wanted_slot_id,
!                    const char *wanted_token_label,
                     unsigned int *slot_num)
  {
    int rv;
***************
*** 995,1001 ****
    rv = -1;
    do {
      /* see if the card we're looking for is inserted */
!     rv = find_slot_by_number_and_label (h, wanted_slot_id,  wanted_slot_label,
                                          slot_num);
      if (rv !=  0) {
        /* could call C_WaitForSlotEvent, for now just poll */
--- 1312,1318 ----
    rv = -1;
    do {
      /* see if the card we're looking for is inserted */
!     rv = find_slot_by_number_and_label (h, wanted_slot_id,  wanted_token_label,
                                          slot_num);
      if (rv !=  0) {
        /* could call C_WaitForSlotEvent, for now just poll */
***************
*** 1306,1312 ****
    return -1;
  }
  
! const char *get_slot_label(pkcs11_handle_t *h)
  {
    return h->slots[h->current_slot].label;
  }
--- 1623,1629 ----
    return -1;
  }
  
! const char *get_slot_tokenlabel(pkcs11_handle_t *h)
  {
    return h->slots[h->current_slot].label;
  }
*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/Makefile.am	Mon May 21 02:46:19 2007
--- pam_pkcs11-WS/src/pam_pkcs11/Makefile.am	Wed Dec  9 13:47:15 2015
***************
*** 2,9 ****
  
  MAINTAINERCLEANFILES = Makefile.in
  
! AM_CFLAGS = -Wall -fno-strict-aliasing $(CRYPTO_CFLAGS)
! AM_CPPFLAGS = -Wall -fno-strict-aliasing $(CRYPTO_CFLAGS)
  
  lib_LTLIBRARIES = pam_pkcs11.la
  
--- 2,9 ----
  
  MAINTAINERCLEANFILES = Makefile.in
  
! AM_CFLAGS = $(CRYPTO_CFLAGS)
! AM_CPPFLAGS = $(CRYPTO_CFLAGS)
  
  lib_LTLIBRARIES = pam_pkcs11.la
  
***************
*** 15,21 ****
  
  install:       
  	$(mkinstalldirs) $(DESTDIR)/$(libdir)/security
! 	$(libLTLIBRARIES_INSTALL) $(top_builddir)/src/pam_pkcs11/.libs/pam_pkcs11.so $(DESTDIR)/$(libdir)/security
  
  format:
  	indent *.c *.h
--- 15,21 ----
  
  install:       
  	$(mkinstalldirs) $(DESTDIR)/$(libdir)/security
! 	$(INSTALL) $(top_builddir)/src/pam_pkcs11/.libs/pam_pkcs11.so $(DESTDIR)/$(libdir)/security
  
  format:
  	indent *.c *.h*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/pam_config.h	Wed Jun  6 02:55:02 2007
--- pam_pkcs11-WS/src/pam_pkcs11/pam_config.h	Mon Sep 28 16:06:48 2009
***************
*** 13,19 ****
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
!  * $Id: pam_config.h 270 2007-05-21 08:13:00Z ludovic.rousseau $
   */
  
  /*
--- 13,19 ----
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
!  * $Id: pam_config.h 341 2008-10-14 07:36:46Z ludovic.rousseau $
   */
  
  /*
***************
*** 38,46 ****
--- 38,48 ----
  	char *pkcs11_module;
  	char *pkcs11_modulepath;
  	char **screen_savers;
+ 	char *slot_description;
  	int slot_num;
  	int support_threads;
  	cert_policy policy;
+ 	char *token_type;
  	char *username; /* provided user name */
  };
  
*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/pam_pkcs11.c	Tue May 22 01:28:33 2007
--- pam_pkcs11-WS/src/pam_pkcs11/pam_pkcs11.c	Mon Nov  2 15:39:57 2009
***************
*** 12,18 ****
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
!  * $Id: pam_pkcs11.c 281 2007-05-22 08:28:40Z ludovic.rousseau $
   */
  
  /* We have to make this definitions before we include the pam header files! */
--- 12,18 ----
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
!  * $Id: pam_pkcs11.c 341 2008-10-14 07:36:46Z ludovic.rousseau $
   */
  
  /* We have to make this definitions before we include the pam header files! */
***************
*** 59,65 ****
  /*
  * comodity function that returns 1 on null, empty o spaced string
  */
! int is_spaced_str(const char *str) {
  	char *pt=(char *)str;
  	if(!str) return 1;
  	if (!strcmp(str,"")) return 1;
--- 59,65 ----
  /*
  * comodity function that returns 1 on null, empty o spaced string
  */
! static int is_spaced_str(const char *str) {
  	char *pt=(char *)str;
  	if(!str) return 1;
  	if (!strcmp(str,"")) return 1;
***************
*** 91,103 ****
    rv = conv->conv(1, (const struct pam_message **)msgp, &resp, conv->appdata_ptr);
    if (rv != PAM_SUCCESS)
      return rv;
!   if ((resp == NULL) || (resp[0].resp == NULL))
      return !response ? PAM_SUCCESS : PAM_CRED_INSUFFICIENT;
    if (response) {
       *response = strdup(resp[0].resp);
    }
    /* overwrite memory and release it */
    memset(resp[0].resp, 0, strlen(resp[0].resp));
    free(&resp[0]);
    return PAM_SUCCESS;
  }
--- 91,106 ----
    rv = conv->conv(1, (const struct pam_message **)msgp, &resp, conv->appdata_ptr);
    if (rv != PAM_SUCCESS)
      return rv;
!   if ((resp == NULL) || (resp[0].resp == NULL)) {
!     free(&resp[0]);
      return !response ? PAM_SUCCESS : PAM_CRED_INSUFFICIENT;
+   }
    if (response) {
       *response = strdup(resp[0].resp);
    }
    /* overwrite memory and release it */
    memset(resp[0].resp, 0, strlen(resp[0].resp));
+   free(resp[0].resp);
    free(&resp[0]);
    return PAM_SUCCESS;
  }
***************
*** 206,211 ****
--- 209,220 ----
  	return PAM_AUTHINFO_UNAVAIL;
    }
  
+   /* Either slot_description or slot_num, but not both, needs to be used */
+   if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) {
+ 	ERR("Error setting configuration parameters");
+ 	return PAM_AUTHINFO_UNAVAIL;
+   }
+ 
    /* fail if we are using a remote server
     * local login: DISPLAY=:0
     * XDMCP login: DISPLAY=host:0 */
***************
*** 274,281 ****
  	    DBG1("explicit username = [%s]", user);
  	} 
    } else {
!         pam_prompt(pamh, PAM_TEXT_INFO, NULL,
!                    _("Please insert your smart card or enter your username."));
  	/* get user name */
  	rv = pam_get_user(pamh, &user, NULL);
  
--- 283,292 ----
  	    DBG1("explicit username = [%s]", user);
  	} 
    } else {
! 	sprintf(password_prompt,
! 		_("Please insert your %s or enter your username."),
! 		_(configuration->token_type));
! 	pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
  	/* get user name */
  	rv = pam_get_user(pamh, &user, NULL);
  
***************
*** 314,321 ****
    }
  
    /* open pkcs #11 session */
!   rv = find_slot_by_number_and_label(ph, configuration->slot_num, 
                                       login_token_name, &slot_num);
    if (rv != 0) {
      ERR("no suitable token available");
      pam_syslog(pamh, LOG_ERR, "no suitable token available");
--- 325,338 ----
    }
  
    /* open pkcs #11 session */
!   if (configuration->slot_description != NULL) {
!     rv = find_slot_by_slotlabel_and_tokenlabel(ph,
!       configuration->slot_description, login_token_name, &slot_num);
!   } else if (configuration->slot_num != -1) {
!     rv = find_slot_by_number_and_label(ph, configuration->slot_num,
                                       login_token_name, &slot_num);
+   }
+ 
    if (rv != 0) {
      ERR("no suitable token available");
      pam_syslog(pamh, LOG_ERR, "no suitable token available");
***************
*** 337,344 ****
          pam_prompt(pamh, PAM_TEXT_INFO, NULL,
                   _("Please insert your smart card."));
        }
!       rv = wait_for_token(ph, configuration->slot_num,
                            login_token_name, &slot_num);
        if (rv != 0) {
          release_pkcs11_module(ph);
          return pkcs11_pam_fail;
--- 354,368 ----
          pam_prompt(pamh, PAM_TEXT_INFO, NULL,
                   _("Please insert your smart card."));
        }
! 
!       if (configuration->slot_description != NULL) {
! 	rv = wait_for_token_by_slotlabel(ph, configuration->slot_description,
!           login_token_name, &slot_num);
!       } else if (configuration->slot_num != -1) {
!         rv = wait_for_token(ph, configuration->slot_num,
                            login_token_name, &slot_num);
+       }
+ 
        if (rv != 0) {
          release_pkcs11_module(ph);
          return pkcs11_pam_fail;
***************
*** 350,362 ****
      } else {
        /* we haven't prompted for the user yet, get the user and see if
         * the smart card has been inserted in the mean time */
!       pam_prompt(pamh, PAM_TEXT_INFO, NULL, 
!                  _("Please insert your smart card or enter your username."));
        rv = pam_get_user(pamh, &user, NULL);
  
        /* check one last time for the smart card before bouncing to the next
         * module */
!       rv = find_slot_by_number(ph, configuration->slot_num, &slot_num);
        if (rv != 0) {
          /* user gave us a user id and no smart card go to next module */
          release_pkcs11_module(ph);
--- 374,394 ----
      } else {
        /* we haven't prompted for the user yet, get the user and see if
         * the smart card has been inserted in the mean time */
!       sprintf(password_prompt,
! 	  	_("Please insert your %s or enter your username."),
! 		_(configuration->token_type));
!       pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
        rv = pam_get_user(pamh, &user, NULL);
  
        /* check one last time for the smart card before bouncing to the next
         * module */
!       if (configuration->slot_description != NULL) {
! 	rv = find_slot_by_slotlabel(ph, configuration->slot_description,
! 	  &slot_num);
!       } else if (configuration->slot_num != -1) {
!         rv = find_slot_by_number(ph, configuration->slot_num, &slot_num);
!       }
! 
        if (rv != 0) {
          /* user gave us a user id and no smart card go to next module */
          release_pkcs11_module(ph);
***************
*** 364,370 ****
        }
      }
    } else {
!       pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Smart card inserted. "));
    }
    rv = open_pkcs11_session(ph, slot_num);
    if (rv != 0) {
--- 396,404 ----
        }
      }
    } else {
!       sprintf(password_prompt, _("Found the %s."),
!          _(configuration->token_type));
!       pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
    }
    rv = open_pkcs11_session(ph, slot_num);
    if (rv != 0) {
***************
*** 375,390 ****
    }
  
    /* get password */
!   sprintf(password_prompt, _("Welcome %.32s!"), get_slot_label(ph));
    pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
    if (configuration->use_first_pass) {
      rv = pam_get_pwd(pamh, &password, NULL, PAM_AUTHTOK, 0);
    } else if (configuration->try_first_pass) {
!     rv = pam_get_pwd(pamh, &password, _("Smart card password: "), PAM_AUTHTOK,
        PAM_AUTHTOK);
    } else {
!     rv = pam_get_pwd(pamh, &password, _("Smart card password: "), 0,
!       PAM_AUTHTOK);
    }
    if (rv != PAM_SUCCESS) {
      release_pkcs11_module(ph);
--- 409,424 ----
    }
  
    /* get password */
!   sprintf(password_prompt, _("Welcome %.32s!"), get_slot_tokenlabel(ph));
    pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
+   sprintf(password_prompt, _("%s PIN: "), _(configuration->token_type));
    if (configuration->use_first_pass) {
      rv = pam_get_pwd(pamh, &password, NULL, PAM_AUTHTOK, 0);
    } else if (configuration->try_first_pass) {
!     rv = pam_get_pwd(pamh, &password, password_prompt, PAM_AUTHTOK,
        PAM_AUTHTOK);
    } else {
!     rv = pam_get_pwd(pamh, &password, password_prompt, 0, PAM_AUTHTOK);
    }
    if (rv != PAM_SUCCESS) {
      release_pkcs11_module(ph);
***************
*** 558,564 ****
    snprintf(env_temp, sizeof(env_temp) - 1,
  	   "PKCS11_LOGIN_TOKEN_NAME=%.*s", 
  	   (sizeof(env_temp) - 1) - strlen("PKCS11_LOGIN_TOKEN_NAME="),
! 	   get_slot_label(ph));
    rv = pam_putenv(pamh, env_temp);
  
    if (rv != PAM_SUCCESS) {
--- 592,598 ----
    snprintf(env_temp, sizeof(env_temp) - 1,
  	   "PKCS11_LOGIN_TOKEN_NAME=%.*s", 
  	   (sizeof(env_temp) - 1) - strlen("PKCS11_LOGIN_TOKEN_NAME="),
! 	   get_slot_tokenlabel(ph));
    rv = pam_putenv(pamh, env_temp);
  
    if (rv != PAM_SUCCESS) {
*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/pam_config.c	Mon May 21 02:46:19 2007
--- pam_pkcs11-WS/src/pam_pkcs11/pam_config.c	Mon Sep 28 16:06:48 2009
***************
*** 20,25 ****
--- 20,26 ----
  
  #include <syslog.h>
  #include <string.h>
+ #include "config.h"
  #include "../scconf/scconf.h"
  #include "../common/debug.h"
  #include "../common/error.h"
***************
*** 27,38 ****
--- 28,45 ----
  #include "pam_config.h"
  #include "mapper_mgr.h"
  
+ #define N_(string) (string)
+ 
  /*
  * configuration related functions
  */
  
  struct configuration_st configuration = {
+ #ifndef ORIGINAL /* SUN_SOLARIS */
+ 	"/etc/security/pam_pkcs11/pam_pkcs11.conf",
+ #else
  	"/etc/pam_pkcs11/pam_pkcs11.conf",	/* char * config_file; */
+ #endif
  	NULL,				/* scconf_context *ctx; */
          0,				/* int debug; */
          0,				/* int nullok; */
***************
*** 44,57 ****
          "default", 			/* const char *pkcs11_module; */
          "/etc/pam_pkcs11/pkcs11_module.so",/* const char *pkcs11_module_path; */
          NULL,                           /* screen savers */
!         0,				/* int slot_num; */
  	0,				/* support threads */
  	/* cert policy; */
          { 0,CRLP_NONE,0,"/etc/pam_pkcs11/cacerts","/etc/pam_pkcs11/crls","/etc/pam_pkcs11/nssdb",OCSP_NONE },
  	NULL				/* char *username */
  };
  
- #if 0
  static void display_config (void) {
          DBG1("debug %d",configuration.debug);
          DBG1("nullok %d",configuration.nullok);
--- 51,65 ----
          "default", 			/* const char *pkcs11_module; */
          "/etc/pam_pkcs11/pkcs11_module.so",/* const char *pkcs11_module_path; */
          NULL,                           /* screen savers */
! 	NULL,				/* slot_description */
!         -1,				/* int slot_num; */
  	0,				/* support threads */
  	/* cert policy; */
          { 0,CRLP_NONE,0,"/etc/pam_pkcs11/cacerts","/etc/pam_pkcs11/crls","/etc/pam_pkcs11/nssdb",OCSP_NONE },
+ 	N_("Smart card"), 		/* token_type */
  	NULL				/* char *username */
  };
  
  static void display_config (void) {
          DBG1("debug %d",configuration.debug);
          DBG1("nullok %d",configuration.nullok);
***************
*** 71,77 ****
          DBG1("signature_policy %d",configuration.policy.signature_policy);
          DBG1("ocsp_policy %d",configuration.policy.ocsp_policy);
  }
- #endif
  
  /*
  parse configuration file
--- 79,84 ----
***************
*** 136,143 ****
--- 143,164 ----
  	        scconf_get_str(pkcs11_mblk,"crl_dir",configuration.policy.crl_dir);
  	    configuration.policy.nss_dir = (char *)
  	        scconf_get_str(pkcs11_mblk,"nss_dir",configuration.policy.nss_dir);
+ 	    configuration.slot_description =  (char *)
+ 	        scconf_get_str(pkcs11_mblk,"slot_description",configuration.slot_description);
+ 
  	    configuration.slot_num = 
  	        scconf_get_int(pkcs11_mblk,"slot_num",configuration.slot_num);
+ 
+ 	    if (configuration.slot_description != NULL && configuration.slot_num != -1) {
+ 		DBG1("Can not specify both slot_description and slot_num in file %s",configuration.config_file);
+ 	            return;
+ 	    }
+ 
+ 	    if (configuration.slot_description == NULL && configuration.slot_num == -1) {
+ 		DBG1("Neither slot_description nor slot_num found in file %s",configuration.config_file);
+ 	            return;
+ 	    }
+ 
  	    configuration.support_threads = 
  	        scconf_get_bool(pkcs11_mblk,"support_threads",configuration.support_threads);
  	    policy_list= scconf_find_list(pkcs11_mblk,"cert_policy");
***************
*** 165,170 ****
--- 186,194 ----
  	        }
  		policy_list= policy_list->next;
  	    }
+ 
+ 	    configuration.token_type = (char *)
+ 		scconf_get_str(pkcs11_mblk,"token_type",configuration.token_type);
  	}
  	screen_saver_list = scconf_find_list(root,"screen_savers");
  	if (screen_saver_list) {
***************
*** 199,205 ****
  	int i;
  	int res;
  	/* try to find a configuration file entry */
! 	for (i = 0; i < argc; i++) {
  	    if (strstr(argv[i],"config_file=") ) {
  		configuration.config_file=1+strchr(argv[i],'=');
  		break;
--- 223,229 ----
  	int i;
  	int res;
  	/* try to find a configuration file entry */
! 	for (i = 1; i < argc; i++) {
  	    if (strstr(argv[i],"config_file=") ) {
  		configuration.config_file=1+strchr(argv[i],'=');
  		break;
***************
*** 211,217 ****
  	/* display_config(); */
  	/* finally parse provided arguments */
  	/* dont skip argv[0] */
! 	for (i = 0; i < argc; i++) {
  	   if (strcmp("nullok", argv[i]) == 0) {
  		configuration.nullok = 1;
  		continue;
--- 235,241 ----
  	/* display_config(); */
  	/* finally parse provided arguments */
  	/* dont skip argv[0] */
! 	for (i = 1; i < argc; i++) {
  	   if (strcmp("nullok", argv[i]) == 0) {
  		configuration.nullok = 1;
  		continue;
***************
*** 246,255 ****
  		res=sscanf(argv[i],"pkcs11_module=%255s",configuration.pkcs11_module);
  		continue;
  	   }
  	   if (strstr(argv[i],"slot_num=") ) {
! 		res=sscanf(argv[i],"slot_nume=%d",&configuration.slot_num);
  		continue;
  	   }
  	   if (strstr(argv[i],"ca_dir=") ) {
  		res=sscanf(argv[i],"ca_dir=%255s",configuration.policy.ca_dir);
  		continue;
--- 270,285 ----
  		res=sscanf(argv[i],"pkcs11_module=%255s",configuration.pkcs11_module);
  		continue;
  	   }
+ 	   if (strstr(argv[i],"slot_description=") ) {
+ 		res=sscanf(argv[i],"slot_description=%255s",configuration.slot_description);
+ 		continue;
+ 	   }
+ 
  	   if (strstr(argv[i],"slot_num=") ) {
! 		res=sscanf(argv[i],"slot_num=%d",&configuration.slot_num);
  		continue;
  	   }
+ 
  	   if (strstr(argv[i],"ca_dir=") ) {
  		res=sscanf(argv[i],"ca_dir=%255s",configuration.policy.ca_dir);
  		continue;
***************
*** 289,294 ****
--- 319,330 ----
  		}
  		continue;
  	   }
+ 
+ 	   if (strstr(argv[i],"token_type=") ) {
+ 		res=sscanf(argv[i],"token_type=%255s",configuration.token_type);
+ 		continue;
+ 	   }
+ 
  	   if (strstr(argv[i],"config_file=") ) {
  		/* already parsed, skip */
  		continue;
***************
*** 299,302 ****
  	}
  	return &configuration;
  }
- 
--- 335,337 ----
*** pam_pkcs11-0.6.0-ORIG/src/mappers/ldap_mapper.c	Wed Jun  6 02:48:24 2007
--- pam_pkcs11-WS/src/mappers/ldap_mapper.c	Mon Sep 28 16:06:48 2009
***************
*** 184,192 ****
  	}
  
  # ifdef HAVE_LDAP_INIT
! 	*ld = ldap_init (uri, defport);
  # else
! 	*ld = ldap_open (uri, defport);
  # endif
  	rc = (*ld == NULL) ? LDAP_SERVER_DOWN : LDAP_SUCCESS;
  
--- 184,192 ----
  	}
  
  # ifdef HAVE_LDAP_INIT
! 	*ld = ldap_init (uri, ldapdefport);
  # else
! 	*ld = ldap_open (uri, ldapdefport);
  # endif
  	rc = (*ld == NULL) ? LDAP_SERVER_DOWN : LDAP_SUCCESS;
  
*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_inspect.c	Mon May 21 02:46:19 2007
--- pam_pkcs11-WS/src/tools/pkcs11_inspect.c	Mon Sep 28 16:06:48 2009
***************
*** 53,58 ****
--- 53,63 ----
  	return 1;
    }
  
+   if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) {
+ 	ERR("Error setting configuration parameters");
+ 	return 1;
+   }
+ 
    /* init openssl */
    rv = crypto_init(&configuration->policy);
    if (rv != 0) {
***************
*** 79,85 ****
    }
  
    /* open pkcs #11 session */
!   rv = find_slot_by_number(ph, configuration->slot_num, &slot_num);
    if (rv != 0) {
      release_pkcs11_module(ph);
      DBG("no token available");
--- 84,95 ----
    }
  
    /* open pkcs #11 session */
!   if (configuration->slot_description != NULL) {
!     rv = find_slot_by_slotlabel(ph, configuration->slot_description, &slot_num);
!   } else {
!     rv = find_slot_by_number(ph, configuration->slot_num, &slot_num);
!   }
! 
    if (rv != 0) {
      release_pkcs11_module(ph);
      DBG("no token available");
*** pam_pkcs11-0.6.0-ORIG/src/tools/pklogin_finder.c	Wed Jun  6 03:00:36 2007
--- pam_pkcs11-WS/src/tools/pklogin_finder.c	Mon Sep 28 16:06:48 2009
***************
*** 55,60 ****
--- 55,65 ----
  	return 1;
    }
  
+   if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) {
+ 	ERR("Error setting configuration parameters");
+ 	return 1;
+   }
+ 
    /* init openssl */
    rv = crypto_init(&configuration->policy);
    if (rv != 0) {
***************
*** 80,86 ****
    }
  
    /* open pkcs #11 session */
!   rv = find_slot_by_number(ph,configuration->slot_num, &slot_num);
    if (rv != 0) {
      release_pkcs11_module(ph);
      DBG("no token available");
--- 85,95 ----
    }
  
    /* open pkcs #11 session */
!   if (configuration->slot_description != NULL) {
!     rv = find_slot_by_slotlabel(ph,configuration->slot_description, &slot_num);
!   } else { 
!     rv = find_slot_by_number(ph,configuration->slot_num, &slot_num);
!   }
    if (rv != 0) {
      release_pkcs11_module(ph);
      DBG("no token available");
*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_eventmgr.c	Wed Jun  6 04:14:27 2007
--- pam_pkcs11-WS/src/tools/pkcs11_eventmgr.c	Mon Sep 28 16:06:48 2009
***************
*** 430,435 ****
--- 430,436 ----
  	}
      }
  
+ #ifdef HAVE_DAEMON
      if (daemonize) {
  	DBG("Going to be daemon...");
  	if ( daemon(0,debug)<0 ) {
***************
*** 440,445 ****
--- 441,447 ----
  		return 1;
  	}
      }
+ #endif 
  
      /* 
       * Wait endlessly for all events in the list of readers
***************
*** 512,517 ****
--- 514,520 ----
      }
  
      /* put my self into background if flag is set */
+ #ifdef HAVE_DAEMON
      if (daemonize) {
  	DBG("Going to be daemon...");
  	if ( daemon(0,debug)<0 ) {
***************
*** 521,526 ****
--- 524,530 ----
  		return 1;
  	}
      }
+ #endif 
  
      /* open pkcs11 sesion */
      DBG("initialising pkcs #11 module...");
*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_listcerts.c	Mon May 21 02:46:19 2007
--- pam_pkcs11-WS/src/tools/pkcs11_listcerts.c	Mon Sep 28 16:06:48 2009
***************
*** 53,58 ****
--- 53,63 ----
  	return 1;
    }
  
+   if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) {
+ 	ERR("Error setting configuration parameters");
+ 	return 1;
+   }
+ 
    /* init openssl */
    rv = crypto_init(&configuration->policy);
    if (rv != 0) {
***************
*** 78,84 ****
    }
  
    /* open pkcs #11 session */
!   rv = find_slot_by_number(ph, configuration->slot_num, &slot_num);
    if (rv != 0) {
      release_pkcs11_module(ph);
      DBG("no token available");
--- 83,94 ----
    }
  
    /* open pkcs #11 session */
!   if (configuration->slot_description != NULL) {
!     rv = find_slot_by_slotlabel(ph,configuration->slot_description, &slot_num);
!   } else { 
!     rv = find_slot_by_number(ph,configuration->slot_num, &slot_num);
!   }
! 
    if (rv != 0) {
      release_pkcs11_module(ph);
      DBG("no token available");
*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_setup.c	Wed Jun  6 04:20:09 2007
--- pam_pkcs11-WS/src/tools/pkcs11_setup.c	Mon Sep 28 16:06:48 2009
***************
*** 60,65 ****
--- 60,92 ----
      return value;
  }
  
+ #ifndef ORIGINAL /* SUN_SOLARIS */
+ /* Written by Niels M\ufffd\ufffdller <[email protected]>
+  * modified by Ludovic Rousseau <[email protected]>
+  *
+  * This file is hereby placed in the public domain.
+  */
+ static char * strndup (const char *s, size_t size)
+ {
+ 	char *r;
+ 	char *end = memchr(s, 0, size);
+ 
+ 	if (NULL == end)
+ 		return NULL;
+ 
+ 	/* Length */
+ 	size = end - s;
+ 
+ 	r = malloc(size+1);
+ 	if (r)
+ 	{
+ 		memcpy(r, s, size);
+ 		r[size] = '\0';
+ 	}
+ 	return r;
+ }
+ #endif
+ 
  static int scconf_replace_str_list(scconf_block * block, const char *option, const char *value)
  {
      scconf_list *list = NULL;
*** pam_pkcs11-0.6.0-ORIG/tools/make_hash_link.sh	Mon May 21 02:46:19 2007
--- pam_pkcs11-WS/tools/make_hash_link.sh	Mon Sep 28 16:06:48 2009
***************
*** 54,60 ****
    hash=`$OPENSSL x509 -inform pem -in $file -noout -hash 2> /dev/null`
    if [ ! -z $hash ]; then
      is_ca=`$OPENSSL x509 -inform pem -in $file -noout -text | grep 'CA:TRUE'`
!     if [ ! -z $is_ca ]; then
        hash=$hash.
        mk_link
      fi
--- 54,60 ----
    hash=`$OPENSSL x509 -inform pem -in $file -noout -hash 2> /dev/null`
    if [ ! -z $hash ]; then
      is_ca=`$OPENSSL x509 -inform pem -in $file -noout -text | grep 'CA:TRUE'`
!     if [ ! -z "$is_ca" ]; then
        hash=$hash.
        mk_link
      fi
***************
*** 63,69 ****
    hash=`$OPENSSL x509 -inform der -in $file -noout -hash 2> /dev/null`
    if [ ! -z $hash ]; then
      is_ca=`$OPENSSL x509 -inform der -in $file -noout -text | grep 'CA:TRUE'`
!     if [ ! -z $is_ca ]; then
        hash=$hash.
        mk_link
      fi
--- 63,69 ----
    hash=`$OPENSSL x509 -inform der -in $file -noout -hash 2> /dev/null`
    if [ ! -z $hash ]; then
      is_ca=`$OPENSSL x509 -inform der -in $file -noout -text | grep 'CA:TRUE'`
!     if [ ! -z "$is_ca" ]; then
        hash=$hash.
        mk_link
      fi