jaas/src/main/java/com/yubico/jaas/YubikeyLoginModule.java
private List<String> get_tokens(NameCallback nameCb) {
		MultiValuePasswordCallback mv_passCb = new MultiValuePasswordCallback("Enter authentication tokens: ", false);
		List<String> result = new ArrayList<String>();

		try {
			/* Fetch a password using the callbackHandler */
			callbackHandler.handle(new Callback[] { nameCb, mv_passCb });

			for (char[] c : mv_passCb.getSecrets()) {
				String s = new String(c);
				/* Check that OTP is at least 32 chars before we verify it. User might have entered
				 * some other password instead of an OTP, and we don't want to send that, possibly
				 * in clear text, over the network.
				 */
				if (s.length() < 32) {
					log.debug("Skipping token, not a valid YubiKey OTP (too short, {} < 32)", s.length());
				} else {
					result.add(s);
				}
			}
		} catch (UnsupportedCallbackException ex) {
			log.error("Callback type not supported", ex);
		} catch (IOException ex) {
			log.error("CallbackHandler failed", ex);
		}
		
		if (jacc) {
			// This is JACC specific mechanism
			try {
				HttpServletRequest request = (HttpServletRequest) PolicyContext
						.getContext(JACC_ATTR_WEB_REQUEST_KEY);
				String j_otp = request.getParameter(HTTP_REQUEST_ATTR_TOTP);
				
				if (j_otp == null || j_otp.length() < 32) {
					log.debug("Skipping token from j_otp, not a valid YubiKey OTP (too short, {} < 32)", j_otp == null ? 0 : j_otp.length());
				} else {
					result.add(j_otp);
				}
				log.debug("OTP from j_otp token : {}", j_otp);
			} catch (PolicyContextException e) {
				log.debug("No OTP from j_otp token)");
			}
		}

		return result;
	}
private List<String> get_tokens(NameCallback nameCb) {
		MultiValuePasswordCallback mv_passCb = new MultiValuePasswordCallback("Enter authentication tokens: ", false);
		List<String> result = new ArrayList<String>();

		try {
			/* Fetch a password using the callbackHandler */
			callbackHandler.handle(new Callback[] { nameCb, mv_passCb });

			for (char[] c : mv_passCb.getSecrets()) {
				String s = new String(c);
				/* Check that OTP is at least 32 chars before we verify it. User might have entered
				 * some other password instead of an OTP, and we don't want to send that, possibly
				 * in clear text, over the network.
				 */
				if (s.length() < 32) {
					log.debug("Skipping token, not a valid YubiKey OTP (too short, {} < 32)", s.length());
				} else {
					result.add(s);
				}
			}
		} catch (UnsupportedCallbackException ex) {
			log.error("Callback type not supported", ex);
		} catch (IOException ex) {
			log.error("CallbackHandler failed", ex);
		}
		
		if (jacc) {
			// This is JACC specific mechanism
			try {
				HttpServletRequest request = (HttpServletRequest) PolicyContext
						.getContext(JACC_ATTR_WEB_REQUEST_KEY);
				String j_otp = request.getParameter(HTTP_REQUEST_ATTR_TOTP);
				
				if (j_otp == null || j_otp.length() < 32) {
					log.debug("Skipping token from j_otp, not a valid YubiKey OTP (too short, {} < 32)", j_otp == null ? 0 : j_otp.length());
				} else {
					result.add(j_otp);
				}
				log.debug("OTP from j_otp token : {}", j_otp);
			} catch (PolicyContextException e) {
				log.debug("No OTP from j_otp token)");
			}
		}

		return result;
	}
private List < String > get_tokens ( NameCallback nameCb ) { MultiValuePasswordCallback mv_passCb = new MultiValuePasswordCallback ( "Enter authentication tokens: " , false ) ; List < String > result = new ArrayList < String > ( ) ; try { /* Fetch a password using the callbackHandler */ callbackHandler . handle ( new Callback [ ] { nameCb , mv_passCb } ) ; for ( char [ ] c : mv_passCb . getSecrets ( ) ) { String s = new String ( c ) ; /* Check that OTP is at least 32 chars before we verify it. User might have entered
				 * some other password instead of an OTP, and we don't want to send that, possibly
				 * in clear text, over the network.
				 */ if ( s . length ( ) < 32 ) { log . debug ( "Skipping token, not a valid YubiKey OTP (too short, {} < 32)" , s . length ( ) ) ; } else { result . add ( s ) ; } } } catch ( UnsupportedCallbackException ex ) { log . error ( "Callback type not supported" , ex ) ; } catch ( IOException ex ) { log . error ( "CallbackHandler failed" , ex ) ; } if ( jacc ) { // This is JACC specific mechanism try { HttpServletRequest request = ( HttpServletRequest ) PolicyContext . getContext ( JACC_ATTR_WEB_REQUEST_KEY ) ; String j_otp = request . getParameter ( HTTP_REQUEST_ATTR_TOTP ) ; if ( j_otp == null || j_otp . length ( ) < 32 ) { log . debug ( "Skipping token from j_otp, not a valid YubiKey OTP (too short, {} < 32)" , j_otp == null ? 0 : j_otp . length ( ) ) ; } else { result . add ( j_otp ) ; } log . debug ( "OTP from j_otp token : {}" , j_otp ) ; } catch ( PolicyContextException e ) { log . debug ( "No OTP from j_otp token)" ) ; } } return result ; }
Get username and token(s) from the application, using the
javax.security.auth.callback.CallbackHandler passed to our initialize()
function.

The tokens returned have been identified as plausible YubiKey OTPs.

@param nameCb
@return list of possible YubiKey OTPs
Get username and token ( s ) from the application using the javax . security . auth . callback . CallbackHandler passed to our initialize () function .