/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. See accompanying LICENSE file.
 */
package org.apache.hadoop.security.authentication.server;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Hashtable;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.InitialDirContext;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.StartTlsRequest;
import javax.naming.ldap.StartTlsResponse;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;

/**
 * The {@link LdapAuthenticationHandler} implements the BASIC authentication
 * mechanism for HTTP using LDAP back-end.
 *
 * The supported configuration properties are:
 * <ul>
 * <li>ldap.providerurl: The url of the LDAP server. It does not have a default
 * value.</li>
 * <li>ldap.basedn: the base distinguished name (DN) to be used with the LDAP
 * server. This value is appended to the provided user id for authentication
 * purpose. It does not have a default value.</li>
 * <li>ldap.binddomain: the LDAP bind domain value to be used with the LDAP
 * server. This property is optional and useful only in case of Active
 * Directory server.
 * <li>ldap.enablestarttls: A boolean value used to define if the LDAP server
 * supports 'StartTLS' extension.</li>
 * </ul>
 */
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class LdapAuthenticationHandler implements AuthenticationHandler {
  private static Logger logger = LoggerFactory
      .getLogger(LdapAuthenticationHandler.class);

  /**
   * Constant that identifies the authentication mechanism.
   */
  public static final String TYPE = "ldap";

  /**
   * Constant that identifies the authentication mechanism to be used with the
   * LDAP server.
   */
  public static final String SECURITY_AUTHENTICATION = "simple";

  /**
   * Constant for the configuration property that indicates the url of the LDAP
   * server.
   */
  public static final String PROVIDER_URL = TYPE + ".providerurl";

  /**
   * Constant for the configuration property that indicates the base
   * distinguished name (DN) to be used with the LDAP server. This value is
   * appended to the provided user id for authentication purpose.
   */
  public static final String BASE_DN = TYPE + ".basedn";

  /**
   * Constant for the configuration property that indicates the LDAP bind
   * domain value to be used with the LDAP server.
   */
  public static final String LDAP_BIND_DOMAIN = TYPE + ".binddomain";

  /**
   * Constant for the configuration property that indicates the base
   * distinguished name (DN) to be used with the LDAP server. This value is
   * appended to the provided user id for authentication purpose.
   */
  public static final String ENABLE_START_TLS = TYPE + ".enablestarttls";

  private String ldapDomain;
  private String baseDN;
  private String providerUrl;
  private Boolean enableStartTls;
  private Boolean disableHostNameVerification;

  /**
   * Configure StartTLS LDAP extension for this handler.
   *
   * @param enableStartTls true If the StartTLS LDAP extension is to be enabled
   *          false otherwise
   */
  @VisibleForTesting
  public void setEnableStartTls(Boolean enableStartTls) {
    this.enableStartTls = enableStartTls;
  }

  /**
   * Configure the Host name verification for this handler. This method is
   * introduced only for unit testing and should never be used in production.
   *
   * @param disableHostNameVerification true to disable host-name verification
   *          false otherwise
   */
  @VisibleForTesting
  public void setDisableHostNameVerification(
      Boolean disableHostNameVerification) {
    this.disableHostNameVerification = disableHostNameVerification;
  }

  @Override
  public String getType() {
    return TYPE;
  }

  @Override
  public void init(Properties config) throws ServletException {
    this.baseDN = config.getProperty(BASE_DN);
    this.providerUrl = config.getProperty(PROVIDER_URL);
    this.ldapDomain = config.getProperty(LDAP_BIND_DOMAIN);
    this.enableStartTls =
        Boolean.valueOf(config.getProperty(ENABLE_START_TLS, "false"));

    Preconditions
        .checkNotNull(this.providerUrl, "The LDAP URI can not be null");
    Preconditions.checkArgument((this.baseDN == null)
        ^ (this.ldapDomain == null),
        "Either LDAP base DN or LDAP domain value needs to be specified");
    if (this.enableStartTls) {
      String tmp = this.providerUrl.toLowerCase();
      Preconditions.checkArgument(!tmp.startsWith("ldaps"),
          "Can not use ldaps and StartTLS option at the same time");
    }
  }

  @Override
  public void destroy() {
  }

  @Override
  public boolean managementOperation(AuthenticationToken token,
      HttpServletRequest request, HttpServletResponse response)
      throws IOException, AuthenticationException {
    return true;
  }

  @Override
  public AuthenticationToken authenticate(HttpServletRequest request,
      HttpServletResponse response)
          throws IOException, AuthenticationException {
    AuthenticationToken token = null;
    String authorization =
        request.getHeader(HttpConstants.AUTHORIZATION_HEADER);

    if (authorization == null
        || !AuthenticationHandlerUtil.matchAuthScheme(HttpConstants.BASIC,
            authorization)) {
      response.setHeader(WWW_AUTHENTICATE, HttpConstants.BASIC);
      response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
      if (authorization == null) {
        logger.trace("Basic auth starting");
      } else {
        logger.warn("'" + HttpConstants.AUTHORIZATION_HEADER
            + "' does not start with '" + HttpConstants.BASIC + "' :  {}",
            authorization);
      }
    } else {
      authorization =
          authorization.substring(HttpConstants.BASIC.length()).trim();
      final Base64 base64 = new Base64(0);
      // As per RFC7617, UTF-8 charset should be used for decoding.
      String[] credentials = new String(base64.decode(authorization),
          StandardCharsets.UTF_8).split(":", 2);
      if (credentials.length == 2) {
        token = authenticateUser(credentials[0], credentials[1]);
        response.setStatus(HttpServletResponse.SC_OK);
      }
    }
    return token;
  }

  private AuthenticationToken authenticateUser(String userName,
      String password) throws AuthenticationException {
    if (userName == null || userName.isEmpty()) {
      throw new AuthenticationException("Error validating LDAP user:"
          + " a null or blank username has been provided");
    }

    // If the domain is available in the config, then append it unless domain
    // is already part of the username. LDAP providers like Active Directory
    // use a fully qualified user name like foo@bar.com.
    if (!hasDomain(userName) && ldapDomain != null) {
      userName = userName + "@" + ldapDomain;
    }

    if (password == null || password.isEmpty() ||
        password.getBytes(StandardCharsets.UTF_8)[0] == 0) {
      throw new AuthenticationException("Error validating LDAP user:"
          + " a null or blank password has been provided");
    }

    // setup the security principal
    String bindDN;
    if (baseDN == null) {
      bindDN = userName;
    } else {
      bindDN = "uid=" + userName + "," + baseDN;
    }

    if (this.enableStartTls) {
      authenticateWithTlsExtension(bindDN, password);
    } else {
      authenticateWithoutTlsExtension(bindDN, password);
    }

    return new AuthenticationToken(userName, userName, TYPE);
  }

  private void authenticateWithTlsExtension(String userDN, String password)
      throws AuthenticationException {
    LdapContext ctx = null;
    Hashtable<String, Object> env = new Hashtable<String, Object>();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
        "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, providerUrl);

    try {
      // Create initial context
      ctx = new InitialLdapContext(env, null);
      // Establish TLS session
      StartTlsResponse tls =
          (StartTlsResponse) ctx.extendedOperation(new StartTlsRequest());

      if (disableHostNameVerification) {
        tls.setHostnameVerifier(new HostnameVerifier() {
          @Override
          public boolean verify(String hostname, SSLSession session) {
            return true;
          }
        });
      }

      tls.negotiate();

      // Initialize security credentials & perform read operation for
      // verification.
      ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION,
          SECURITY_AUTHENTICATION);
      ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
      ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
      ctx.lookup(userDN);
      logger.debug("Authentication successful for {}", userDN);

    } catch (NamingException | IOException ex) {
      throw new AuthenticationException("Error validating LDAP user", ex);
    } finally {
      if (ctx != null) {
        try {
          ctx.close();
        } catch (NamingException e) { /* Ignore. */
        }
      }
    }
  }

  private void authenticateWithoutTlsExtension(String userDN, String password)
      throws AuthenticationException {
    Hashtable<String, Object> env = new Hashtable<String, Object>();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
        "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, providerUrl);
    env.put(Context.SECURITY_AUTHENTICATION, SECURITY_AUTHENTICATION);
    env.put(Context.SECURITY_PRINCIPAL, userDN);
    env.put(Context.SECURITY_CREDENTIALS, password);

    try {
      // Create initial context
      Context ctx = new InitialDirContext(env);
      ctx.close();
      logger.debug("Authentication successful for {}", userDN);

    } catch (NamingException e) {
      throw new AuthenticationException("Error validating LDAP user", e);
    }
  }

  private static boolean hasDomain(String userName) {
    return (indexOfDomainMatch(userName) > 0);
  }

  /*
   * Get the index separating the user name from domain name (the user's name
   * up to the first '/' or '@').
   *
   * @param userName full user name.
   *
   * @return index of domain match or -1 if not found
   */
  private static int indexOfDomainMatch(String userName) {
    if (userName == null) {
      return -1;
    }

    int idx = userName.indexOf('/');
    int idx2 = userName.indexOf('@');
    int endIdx = Math.min(idx, idx2); // Use the earlier match.
    // Unless at least one of '/' or '@' was not found, in
    // which case, user the latter match.
    if (endIdx == -1) {
      endIdx = Math.max(idx, idx2);
    }
    return endIdx;
  }

}