* Applications that don't know about protectedPinAuth will return a
* Applications that don't know about protectedAuthPath will return a
PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx){    SECStatus rv = SECFailure;    char * password;    PRBool attempt = PR_FALSE;    if (PK11_NeedUserInit(slot)) {	PORT_SetError(SEC_ERROR_IO);	return SECFailure;    }    /*     * Central server type applications which control access to multiple     * slave applications to single crypto devices need to virtuallize the     * login state. This is done by a callback out of PK11_IsLoggedIn and     * here. If we are actually logged in, then we got here because the     * higher level code told us that the particular client application may     * still need to be logged in. If that is the case, we simply tell the     * server code that it should now verify the clients password and tell us     * the results.     */    if (PK11_IsLoggedIn(slot,NULL) &&     			(PK11_Global.verifyPass != NULL)) {	if (!PK11_Global.verifyPass(slot,wincx)) {	    PORT_SetError(SEC_ERROR_BAD_PASSWORD);	    return SECFailure;	}	return SECSuccess;    }    /* get the password. This can drop out of the while loop     * for the following reasons:     * 	(1) the user refused to enter a password.      *			(return error to caller)     *	(2) the token user password is disabled [usually due to     *	   too many failed authentication attempts].     *			(return error to caller)     *	(3) the password was successful.     */    while ((password = pk11_GetPassword(slot, attempt, wincx)) != NULL) {	/* if the token has a protectedAuthPath, the application may have         * already issued the C_Login as part of it's pk11_GetPassword call.         * In this case the application will tell us what the results were in          * the password value (retry or the authentication was successful) so	 * we can skip our own C_Login call (which would force the token to	 * try to login again).	 * 	 * Applications that don't know about protectedPinAuth will return a 	 * password, which we will ignore and trigger the token to 	 * 'authenticate' itself anyway. Hopefully the blinking display on 	 * the reader, or the flashing light under the thumbprint reader will 	 * attract the user's attention */	attempt = PR_TRUE;	if (slot->protectedAuthPath) {	    /* application tried to authenticate and failed. it wants to try	     * again, continue looping */	    if (strcmp(password, PK11_PW_RETRY) == 0) {		rv = SECWouldBlock;		PORT_Free(password);		break;	     /* applicaton tried to authenticate and succeeded we're done */	     } else if (strcmp(password, PK11_PW_AUTHENTICATED) == 0) {		rv = SECSuccess;		PORT_Free(password);		break;	     }	}	rv = pk11_CheckPassword(slot,password);	PORT_Memset(password, 0, PORT_Strlen(password));	PORT_Free(password);	if (rv != SECWouldBlock) break;    }    if (rv == SECSuccess) {	rv = pk11_CheckVerifyTest(slot);	if (!PK11_IsFriendly(slot)) {	    nssTrustDomain_UpdateCachedTokenCerts(slot->nssToken->trustDomain,	                                      slot->nssToken);	}    } else if (!attempt) PORT_SetError(SEC_ERROR_BAD_PASSWORD);    return rv;}