All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ldaptive.auth.ext.FreeIPAAuthenticationResponseHandler Maven / Gradle / Ivy

There is a newer version: 2.3.2
Show newest version
/*
  $Id: FreeIPAAuthenticationResponseHandler.java 3189 2016-11-01 21:21:43Z daniel_fisher $

  Copyright (C) 2003-2014 Virginia Tech.
  All rights reserved.

  SEE LICENSE FOR MORE INFORMATION

  Author:  Middleware Services
  Email:   [email protected]
  Version: $Revision: 3189 $
  Updated: $Date: 2016-11-01 17:21:43 -0400 (Tue, 01 Nov 2016) $
*/
package org.ldaptive.auth.ext;

import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import org.ldaptive.LdapAttribute;
import org.ldaptive.LdapEntry;
import org.ldaptive.LdapUtils;
import org.ldaptive.ResultCode;
import org.ldaptive.auth.AuthenticationResponse;
import org.ldaptive.auth.AuthenticationResponseHandler;
import org.ldaptive.io.GeneralizedTimeValueTranscoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Attempts to parse the authentication response and set the account state
 * using data associated with FreeIPA. The {@link
 * org.ldaptive.auth.Authenticator} should be configured to return
 * 'krbPasswordExpiration', 'krbLoginFailedCount' and 'krbLastPwdChange'
 * attributes so they can be consumed by this handler.
 *
 * @author  tduehr
 * @version  $Revision: 3189 $
 */
public class FreeIPAAuthenticationResponseHandler
  implements AuthenticationResponseHandler
{

  /** hash code seed. */
  private static final int HASH_CODE_SEED = 1217;

  /** Logger for this class. */
  protected final Logger logger = LoggerFactory.getLogger(getClass());

  /** Maximum password age in days. */
  private int maxPasswordAge;

  /** Maximum password age. */
  private int maxLoginFailures;

  /** Number of hours before expiration to produce a warning. */
  private int warningHours;


  /** Default constructor. */
  public FreeIPAAuthenticationResponseHandler() {}


  /**
   * Creates a new freeipa authentication response handler.
   *
   * @param  warning  length of time before expiration that should produce a
   * warning
   * @param  passwordAge  length of time in days that a password is valid
   * @param  loginFailures  number of login failures to allow
   */
  public FreeIPAAuthenticationResponseHandler(
    final int warning,
    final int passwordAge,
    final int loginFailures)
  {
    if (warning < 0) {
      throw new IllegalArgumentException("Warning hours must be >= 0");
    }
    warningHours = warning;
    if (passwordAge < 0) {
      throw new IllegalArgumentException("Password age must be >= 0");
    }
    maxPasswordAge = passwordAge;
    if (loginFailures < 0) {
      throw new IllegalArgumentException("Login failures must be >= 0");
    }
    maxLoginFailures = loginFailures;
  }


  /**
   * Creates a new freeipa authentication response handler.
   *
   * @param  warning  length of time before expiration that should produce a
   * warning
   * @param  passwordAge  length of time in days that a password is valid
   * @param  loginFailures  number of login failures to allow
   */
  public FreeIPAAuthenticationResponseHandler(
    final String warning,
    final String passwordAge,
    final int loginFailures)
  {
    this(
      (int) LdapUtils.durationDecode(warning, TimeUnit.HOURS),
      (int) LdapUtils.durationDecode(passwordAge, TimeUnit.DAYS),
      loginFailures);
  }


  @Override
  public void handle(final AuthenticationResponse response)
  {
    if (response.getResultCode() != ResultCode.SUCCESS) {
      final FreeIPAAccountState.Error fError = FreeIPAAccountState.Error.parse(
        response.getResultCode(),
        response.getMessage());
      if (fError != null) {
        response.setAccountState(new FreeIPAAccountState(fError));
      }
    } else if (response.getResult()) {
      final LdapEntry entry = response.getLdapEntry();
      final LdapAttribute expTime = entry.getAttribute(
        "krbPasswordExpiration");
      final LdapAttribute failedLogins = entry.getAttribute(
        "krbLoginFailedCount");
      final LdapAttribute lastPwdChange = entry.getAttribute(
        "krbLastPwdChange");
      Calendar exp = null;

      Integer loginRemaining = null;
      if (failedLogins != null && maxLoginFailures > 0) {
        loginRemaining = maxLoginFailures - Integer.parseInt(
          failedLogins.getStringValue());
      }

      final Calendar now = Calendar.getInstance();
      if (expTime != null) {
        exp = expTime.getValue(new GeneralizedTimeValueTranscoder());
      } else if (maxPasswordAge > 0 && lastPwdChange != null) {
        exp = lastPwdChange.getValue(new GeneralizedTimeValueTranscoder());
        exp.setTimeInMillis(
          exp.getTimeInMillis() + TimeUnit.DAYS.toMillis(maxPasswordAge));
      }
      if (exp != null) {
        if (warningHours > 0) {
          final Calendar warn = (Calendar) exp.clone();
          warn.add(Calendar.HOUR_OF_DAY, -warningHours);
          if (now.after(warn)) {
            response.setAccountState(
              new FreeIPAAccountState(
                exp,
                loginRemaining != null ? loginRemaining.intValue() : 0));
          }
        } else {
          response.setAccountState(
            new FreeIPAAccountState(
              exp,
              loginRemaining != null ? loginRemaining.intValue() : 0));
        }
      } else if (loginRemaining != null) {
        response.setAccountState(
          new FreeIPAAccountState(null, loginRemaining));
      }
    }
  }


  /** {@inheritDoc} */
  @Override
  public boolean equals(final Object o)
  {
    if (o == this) {
      return true;
    }
    if (o instanceof FreeIPAAuthenticationResponseHandler) {
      final FreeIPAAuthenticationResponseHandler v =
        (FreeIPAAuthenticationResponseHandler) o;
      return LdapUtils.areEqual(maxPasswordAge, v.maxPasswordAge) &&
             LdapUtils.areEqual(maxLoginFailures, v.maxLoginFailures) &&
             LdapUtils.areEqual(warningHours, v.warningHours);
    }
    return false;
  }


  /** {@inheritDoc} */
  @Override
  public int hashCode()
  {
    return
      LdapUtils.computeHashCode(
        HASH_CODE_SEED,
        maxPasswordAge,
        maxLoginFailures,
        warningHours);
  }


  @Override
  public String toString()
  {
    return String.format(
      "[%s@%d::maxPasswordAge=%s, maxLoginFailures=%s, warningHours=%s]",
      getClass().getName(),
      hashCode(),
      maxPasswordAge,
      maxLoginFailures,
      warningHours);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy