use of com.sun.identity.authentication.spi.InvalidPasswordException in project OpenAM by OpenRock.
the class OATH method setLoginTime.
/**
* Sets the last login time and time-step drift of a user.
*
* @param id The id of the user to set the attribute of.
* @param timeStep The time step of the login.
* @throws AuthLoginException on any error.
*/
private void setLoginTime(AMIdentity id, long timeStep) throws AuthLoginException {
// set login time converting back to seconds
Map<String, Set<String>> attrMap = new HashMap<String, Set<String>>();
Set<String> loginTimeInSeconds = Collections.singleton(Long.toString(timeStep * totpTimeStep));
attrMap.put(loginTimeAttrName, loginTimeInSeconds);
long observedClockDrift = 0;
if (clockDriftCheckEnabled) {
// Update the observed time-step drift for resynchronisation
observedClockDrift = timeStep - (timeInSeconds / totpTimeStep);
if (Math.abs(observedClockDrift) > totpMaxClockDrift) {
setFailureID(userName);
throw new InvalidPasswordException(amAuthOATH, "outOfSync", null, userName, null);
}
// convert drift step back to seconds
Set<String> clockDriftValue = Collections.singleton(Long.toString((int) observedClockDrift * totpTimeStep));
attrMap.put(observedClockDriftAttrName, clockDriftValue);
}
try {
id.setAttributes(attrMap);
id.store();
} catch (IdRepoException e) {
String driftMsg = clockDriftCheckEnabled ? " observedClockDrift:" + observedClockDrift : "";
debug.error("OATH.setLoginTime: error setting attributes time: " + timeStep + driftMsg, e);
throw new AuthLoginException(amAuthOATH, "authFailed", null);
} catch (SSOException e) {
debug.error("OATH.setLoginTime: error invalid token for id : " + id, e);
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
return;
}
use of com.sun.identity.authentication.spi.InvalidPasswordException in project OpenAM by OpenRock.
the class OATH method checkOTP.
/**
* Checks the input OTP
*
* @param otp The OTP to verify
* @return true if the OTP is valid; false if the OTP is invalid, or out of
* sync with server.
* @throws AuthLoginException on any error
*/
private boolean checkOTP(String otp) throws AuthLoginException {
//get user id
AMIdentity id = null;
id = getIdentity(userName);
if (id == null) {
// error message already printed in the getIdentity function
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
byte[] secretKeyBytes = getSharedSecret(id);
String otpGen = null;
try {
if (algorithm == HOTP) {
/*
* HOTP check section
*/
int counter = 0;
Set<String> counterSet = null;
try {
if (StringUtils.isEmpty(counterAttrName)) {
debug.error("OATH" + ".checkOTP() : " + "invalid counter attribute name : ");
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
counterSet = id.getAttribute(counterAttrName);
} catch (IdRepoException e) {
debug.error("OATH" + ".checkOTP() : " + "error getting counter attribute : ", e);
throw new AuthLoginException(amAuthOATH, "authFailed", null);
} catch (SSOException e) {
debug.error("OATH" + ".checkOTP() : " + "error invalid repo id : " + id, e);
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
//check counter value
if (counterSet == null || counterSet.isEmpty()) {
//throw exception
debug.error("OATH" + ".checkOTP() : " + "Counter value is empty or null");
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
try {
counter = Integer.parseInt((String) (counterSet.iterator().next()));
} catch (NumberFormatException e) {
debug.error("OATH" + ".checkOTP() : " + "Counter is not a valid number", e);
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
//check window size
if (windowSize < 0) {
debug.error("OATH" + ".checkOTP() : " + "Window size is not valid");
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
// we have to do counter+1 because counter is the last previous
//accepted counter
counter++;
//test the counter in the lookahead window
for (int i = 0; i <= windowSize; i++) {
otpGen = HOTPAlgorithm.generateOTP(secretKeyBytes, counter + i, passLen, checksum, truncationOffset);
if (isEqual(otpGen, otp)) {
//OTP is correct set the counter value to counter+i
setCounterAttr(id, counter + i);
return true;
}
}
} else if (algorithm == TOTP) {
validateTOTPParameters();
clockDriftCheckEnabled = !StringUtils.isEmpty(observedClockDriftAttrName);
Set attrNames = new HashSet();
String lastLoginTimeAttrValue = "";
String lastObservedClockDriftAttr = null;
Map<String, Set<String>> totpAttributeValues = null;
long lastClockDriftInSeconds = 0;
long lastLoginTimeInSeconds = 0;
attrNames.add(loginTimeAttrName);
if (clockDriftCheckEnabled) {
attrNames.add(observedClockDriftAttrName);
}
try {
totpAttributeValues = id.getAttributes(attrNames);
if (!totpAttributeValues.isEmpty()) {
lastLoginTimeAttrValue = CollectionHelper.getMapAttr(totpAttributeValues, loginTimeAttrName);
if (lastLoginTimeAttrValue != null && !lastLoginTimeAttrValue.isEmpty()) {
lastLoginTimeInSeconds = Long.parseLong(lastLoginTimeAttrValue);
}
if (lastLoginTimeInSeconds < 0) {
debug.error("OATH.checkOTP(): invalid login time value: " + lastLoginTimeInSeconds);
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
if (clockDriftCheckEnabled) {
lastObservedClockDriftAttr = CollectionHelper.getMapAttr(totpAttributeValues, observedClockDriftAttrName);
if (!StringUtils.isEmpty(lastObservedClockDriftAttr)) {
lastClockDriftInSeconds = Long.parseLong(lastObservedClockDriftAttr);
} else {
if (debug.messageEnabled()) {
debug.message("OATH.checkOTP(): last observed time drift Set was empty");
}
}
}
} else {
debug.error("OATH.checkOTP(): error TOTP attributes were empty");
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
} catch (IdRepoException e) {
debug.error("OATH.checkOTP(): error getting TOTP attributes : ", e);
throw new AuthLoginException(amAuthOATH, "authFailed", null);
} catch (SSOException e) {
debug.error("OATH.checkOTP(): error invalid repo id : " + id, e);
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
// convert last login time in seconds to TOTP time steps
long lastLoginTimeStep = lastLoginTimeInSeconds / totpTimeStep;
// get the current time step based on arrival time of OTP
long currentTimeStep = (timeInSeconds / totpTimeStep) + (lastClockDriftInSeconds / totpTimeStep);
if (lastLoginTimeStep == currentTimeStep) {
debug.error("OATH.checkOTP(): Login failed attempting to use the same OTP in same Time Step: " + currentTimeStep);
throw new InvalidPasswordException(amAuthOATH, "authFailed", null, userName, null);
}
boolean sameWindow = false;
// logins within the window using the same OTP
if (lastLoginTimeStep >= (currentTimeStep - totpStepsInWindow) && lastLoginTimeStep <= (currentTimeStep + totpStepsInWindow)) {
if (debug.messageEnabled()) {
debug.message("OATH.checkOTP(): Login in the same TOTP window");
}
sameWindow = true;
}
if (debug.messageEnabled()) {
debug.message("OATH.checkOTP(): values lastLoginTimeInSeconds: " + lastLoginTimeInSeconds + " lastLoginTimeStep: " + lastLoginTimeStep + " sameWindow:" + sameWindow + " \n clockDriftSeconds: " + lastClockDriftInSeconds + " clockDriftCheckEnabled: " + clockDriftCheckEnabled);
}
String passLenStr = Integer.toString(passLen);
otpGen = TOTPAlgorithm.generateTOTP(secretKeyBytes, Long.toHexString(currentTimeStep), passLenStr);
if (isEqual(otpGen, otp)) {
setLoginTime(id, currentTimeStep);
return true;
}
for (int curTimeStepOffSet = 1; curTimeStepOffSet <= totpStepsInWindow; curTimeStepOffSet++) {
long timeInFutureStep = currentTimeStep + curTimeStepOffSet;
long timeInPastStep = currentTimeStep - curTimeStepOffSet;
// check time step after current time
otpGen = TOTPAlgorithm.generateTOTP(secretKeyBytes, Long.toHexString(timeInFutureStep), passLenStr);
if (isEqual(otpGen, otp)) {
setLoginTime(id, timeInFutureStep);
return true;
}
// check time step before current time
otpGen = TOTPAlgorithm.generateTOTP(secretKeyBytes, Long.toHexString(timeInPastStep), passLenStr);
if (isEqual(otpGen, otp) && sameWindow) {
debug.error("OATH.checkOTP(): " + "Login the same window with a OTP that is older than the current OTP");
return false;
} else if (isEqual(otpGen, otp) && !sameWindow) {
setLoginTime(id, timeInPastStep);
return true;
}
}
} else {
debug.error("OATH.checkOTP(): No OTP algorithm selected");
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
} catch (AuthLoginException e) {
// Re-throw to avoid the catch-all block below that would log and lose the error message.
throw e;
} catch (Exception e) {
debug.error("OATH.checkOTP(): checkOTP process failed : ", e);
throw new AuthLoginException(amAuthOATH, "authFailed", null);
}
return false;
}
use of com.sun.identity.authentication.spi.InvalidPasswordException in project OpenAM by OpenRock.
the class HOTP method process.
public int process(Callback[] callbacks, int state) throws AuthLoginException {
if (skip) {
debug.message("Skipping HOTP module");
return ISAuthConstants.LOGIN_SUCCEED;
}
if (userName == null || userName.length() == 0) {
throw new AuthLoginException("amAuth", "noUserName", null);
}
if (state == 1) {
if (hotpAutoClicking) {
debug.message("Auto sending OTP code");
try {
hotpService.sendHOTP();
substituteHeader(START_STATE, bundle.getString("send.success"));
} catch (AuthLoginException ale) {
throw new AuthErrorCodeException(AMAuthErrorCode.AUTH_ERROR, amAuthHOTP, "send.failure");
}
}
return START_STATE;
}
currentState = state;
int action = 0;
try {
if (currentState == START_STATE) {
// action = 1 is Request HOTP Code Button
if (callbacks != null && callbacks.length == 2) {
action = ((ConfirmationCallback) callbacks[1]).getSelectedIndex();
if (debug.messageEnabled()) {
debug.message("HOTP.process() : " + "LOGIN page button index: " + action);
}
if (action == 0) {
//Submit HOTP Code
enteredHOTPCode = String.valueOf(((PasswordCallback) callbacks[0]).getPassword());
if (enteredHOTPCode == null || enteredHOTPCode.length() == 0) {
if (debug.messageEnabled()) {
debug.message("HOTP.process() : " + "invalid HOTP code");
}
setFailureID(userName);
throw new InvalidPasswordException("amAuth", "invalidPasswd", null);
}
// Enforce the code validate time HOTP module config
if (hotpService.isValidHOTP(enteredHOTPCode)) {
return ISAuthConstants.LOGIN_SUCCEED;
} else {
setFailureID(userName);
throw new InvalidPasswordException("amAuth", "invalidPasswd", null);
}
} else {
// Send HOTP Code
try {
hotpService.sendHOTP();
substituteHeader(START_STATE, bundle.getString("send.success"));
} catch (AuthLoginException ale) {
throw new AuthErrorCodeException(AMAuthErrorCode.AUTH_ERROR, amAuthHOTP, "send.failure");
}
return START_STATE;
}
} else {
setFailureID(userName);
throw new AuthLoginException(amAuthHOTP, "authFailed", null);
}
} else {
setFailureID(userName);
throw new AuthLoginException(amAuthHOTP, "authFailed", null);
}
} catch (NumberFormatException ex) {
debug.error("HOTP.process() : NumberFormatException Exception", ex);
if (userName != null && userName.length() != 0) {
setFailureID(userName);
}
throw new AuthLoginException(amAuthHOTP, "authFailed", null, ex);
}
}
Aggregations