/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

package org.apache.hadoop.security;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.RealmCallback;
import javax.security.sasl.RealmChoiceCallback;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslClient;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.io.WritableUtils;
import org.apache.hadoop.ipc.RemoteException;
import org.apache.hadoop.security.SaslRpcServer.AuthMethod;
import org.apache.hadoop.security.SaslRpcServer.SaslStatus;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.TokenIdentifier;

/**
 * A utility class that encapsulates SASL logic for RPC client
 */
@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
@InterfaceStability.Evolving
public class SaslRpcClient {
  public static final Log LOG = LogFactory.getLog(SaslRpcClient.class);

  private final SaslClient saslClient;

  /**
   * Create a SaslRpcClient for an authentication method
   * 
   * @param method
   *          the requested authentication method
   * @param token
   *          token to use if needed by the authentication method
   */
  public SaslRpcClient(AuthMethod method,
      Token<? extends TokenIdentifier> token, String serverPrincipal)
      throws IOException {
    switch (method) {
    case DIGEST:
      if (LOG.isDebugEnabled())
        LOG.debug("Creating SASL " + AuthMethod.DIGEST.getMechanismName()
            + " client to authenticate to service at " + token.getService());
      saslClient = Sasl.createSaslClient(new String[] { AuthMethod.DIGEST
          .getMechanismName() }, null, null, SaslRpcServer.SASL_DEFAULT_REALM,
          SaslRpcServer.SASL_PROPS, new SaslClientCallbackHandler(token));
      break;
    case KERBEROS:
      if (LOG.isDebugEnabled()) {
        LOG.debug("Creating SASL " + AuthMethod.KERBEROS.getMechanismName()
            + " client. Server's Kerberos principal name is "
            + serverPrincipal);
      }
      if (serverPrincipal == null || serverPrincipal.length() == 0) {
        throw new IOException(
            "Failed to specify server's Kerberos principal name");
      }
      String names[] = SaslRpcServer.splitKerberosName(serverPrincipal);
      if (names.length != 3) {
        throw new IOException(
          "Kerberos principal name does NOT have the expected hostname part: "
                + serverPrincipal);
      }
      saslClient = Sasl.createSaslClient(new String[] { AuthMethod.KERBEROS
          .getMechanismName() }, null, names[0], names[1],
          SaslRpcServer.SASL_PROPS, null);
      break;
    default:
      throw new IOException("Unknown authentication method " + method);
    }
    if (saslClient == null)
      throw new IOException("Unable to find SASL client implementation");
  }

  private static void readStatus(DataInputStream inStream) throws IOException {
    int status = inStream.readInt(); // read status
    if (status != SaslStatus.SUCCESS.state) {
      throw new RemoteException(WritableUtils.readString(inStream),
          WritableUtils.readString(inStream));
    }
  }
  
  /**
   * Do client side SASL authentication with server via the given InputStream
   * and OutputStream
   * 
   * @param inS
   *          InputStream to use
   * @param outS
   *          OutputStream to use
   * @return true if connection is set up, or false if needs to switch 
   *             to simple Auth.
   * @throws IOException
   */
  public boolean saslConnect(InputStream inS, OutputStream outS)
      throws IOException {
    DataInputStream inStream = new DataInputStream(new BufferedInputStream(inS));
    DataOutputStream outStream = new DataOutputStream(new BufferedOutputStream(
        outS));

    try {
      byte[] saslToken = new byte[0];
      if (saslClient.hasInitialResponse())
        saslToken = saslClient.evaluateChallenge(saslToken);
      if (saslToken != null) {
        outStream.writeInt(saslToken.length);
        outStream.write(saslToken, 0, saslToken.length);
        outStream.flush();
        if (LOG.isDebugEnabled())
          LOG.debug("Have sent token of size " + saslToken.length
              + " from initSASLContext.");
      }
      if (!saslClient.isComplete()) {
        readStatus(inStream);
        int len = inStream.readInt();
        if (len == SaslRpcServer.SWITCH_TO_SIMPLE_AUTH) {
          if (LOG.isDebugEnabled())
            LOG.debug("Server asks us to fall back to simple auth.");
          saslClient.dispose();
          return false;
        }
        saslToken = new byte[len];
        if (LOG.isDebugEnabled())
          LOG.debug("Will read input token of size " + saslToken.length
              + " for processing by initSASLContext");
        inStream.readFully(saslToken);
      }

      while (!saslClient.isComplete()) {
        saslToken = saslClient.evaluateChallenge(saslToken);
        if (saslToken != null) {
          if (LOG.isDebugEnabled())
            LOG.debug("Will send token of size " + saslToken.length
                + " from initSASLContext.");
          outStream.writeInt(saslToken.length);
          outStream.write(saslToken, 0, saslToken.length);
          outStream.flush();
        }
        if (!saslClient.isComplete()) {
          readStatus(inStream);
          saslToken = new byte[inStream.readInt()];
          if (LOG.isDebugEnabled())
            LOG.debug("Will read input token of size " + saslToken.length
                + " for processing by initSASLContext");
          inStream.readFully(saslToken);
        }
      }
      if (LOG.isDebugEnabled()) {
        LOG.debug("SASL client context established. Negotiated QoP: "
            + saslClient.getNegotiatedProperty(Sasl.QOP));
      }
      return true;
    } catch (IOException e) {
      try {
        saslClient.dispose();
      } catch (SaslException ignored) {
        // ignore further exceptions during cleanup
      }
      throw e;
    }
  }

  /**
   * Get a SASL wrapped InputStream. Can be called only after saslConnect() has
   * been called.
   * 
   * @param in
   *          the InputStream to wrap
   * @return a SASL wrapped InputStream
   * @throws IOException
   */
  public InputStream getInputStream(InputStream in) throws IOException {
    if (!saslClient.isComplete()) {
      throw new IOException("Sasl authentication exchange hasn't completed yet");
    }
    return new SaslInputStream(in, saslClient);
  }

  /**
   * Get a SASL wrapped OutputStream. Can be called only after saslConnect() has
   * been called.
   * 
   * @param out
   *          the OutputStream to wrap
   * @return a SASL wrapped OutputStream
   * @throws IOException
   */
  public OutputStream getOutputStream(OutputStream out) throws IOException {
    if (!saslClient.isComplete()) {
      throw new IOException("Sasl authentication exchange hasn't completed yet");
    }
    return new SaslOutputStream(out, saslClient);
  }

  /** Release resources used by wrapped saslClient */
  public void dispose() throws SaslException {
    saslClient.dispose();
  }

  private static class SaslClientCallbackHandler implements CallbackHandler {
    private final String userName;
    private final char[] userPassword;

    public SaslClientCallbackHandler(Token<? extends TokenIdentifier> token) {
      this.userName = SaslRpcServer.encodeIdentifier(token.getIdentifier());
      this.userPassword = SaslRpcServer.encodePassword(token.getPassword());
    }

    public void handle(Callback[] callbacks)
        throws UnsupportedCallbackException {
      NameCallback nc = null;
      PasswordCallback pc = null;
      RealmCallback rc = null;
      for (Callback callback : callbacks) {
        if (callback instanceof RealmChoiceCallback) {
          continue;
        } else if (callback instanceof NameCallback) {
          nc = (NameCallback) callback;
        } else if (callback instanceof PasswordCallback) {
          pc = (PasswordCallback) callback;
        } else if (callback instanceof RealmCallback) {
          rc = (RealmCallback) callback;
        } else {
          throw new UnsupportedCallbackException(callback,
              "Unrecognized SASL client callback");
        }
      }
      if (nc != null) {
        if (LOG.isDebugEnabled())
          LOG.debug("SASL client callback: setting username: " + userName);
        nc.setName(userName);
      }
      if (pc != null) {
        if (LOG.isDebugEnabled())
          LOG.debug("SASL client callback: setting userPassword");
        pc.setPassword(userPassword);
      }
      if (rc != null) {
        if (LOG.isDebugEnabled())
          LOG.debug("SASL client callback: setting realm: "
              + rc.getDefaultText());
        rc.setText(rc.getDefaultText());
      }
    }
  }
}
