/*
 * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch>
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.eclipse.jgit.internal.transport.sshd;

import static java.text.MessageFormat.format;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.Iterator;

import org.apache.sshd.client.auth.AbstractUserAuth;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.MessageProp;
import org.ietf.jgss.Oid;

/**
 * GSSAPI-with-MIC authentication handler (Kerberos 5).
 *
 * @see <a href="https://tools.ietf.org/html/rfc4462">RFC 4462</a>
 */
public class GssApiWithMicAuthentication extends AbstractUserAuth {

	/** Synonym used in RFC 4462. */
	private static final byte SSH_MSG_USERAUTH_GSSAPI_RESPONSE = SshConstants.SSH_MSG_USERAUTH_INFO_REQUEST;

	/** Synonym used in RFC 4462. */
	private static final byte SSH_MSG_USERAUTH_GSSAPI_TOKEN = SshConstants.SSH_MSG_USERAUTH_INFO_RESPONSE;

	private enum ProtocolState {
		STARTED, TOKENS, MIC_SENT, FAILED
	}

	private Collection<Oid> mechanisms;

	private Iterator<Oid> nextMechanism;

	private Oid currentMechanism;

	private ProtocolState state;

	private GSSContext context;

	/** Creates a new {@link GssApiWithMicAuthentication}. */
	public GssApiWithMicAuthentication() {
		super(GssApiWithMicAuthFactory.NAME);
	}

	@Override
	protected boolean sendAuthDataRequest(ClientSession session, String service)
			throws Exception {
		if (mechanisms == null) {
			mechanisms = GssApiMechanisms.getSupportedMechanisms();
			nextMechanism = mechanisms.iterator();
		}
		if (context != null) {
			close(false);
		}
		if (!nextMechanism.hasNext()) {
			return false;
		}
		state = ProtocolState.STARTED;
		currentMechanism = nextMechanism.next();
		// RFC 4462 states that SPNEGO must not be used with ssh
		while (GssApiMechanisms.SPNEGO.equals(currentMechanism)) {
			if (!nextMechanism.hasNext()) {
				return false;
			}
			currentMechanism = nextMechanism.next();
		}
		try {
			String hostName = getHostName(session);
			context = GssApiMechanisms.createContext(currentMechanism,
					hostName);
			context.requestMutualAuth(true);
			context.requestConf(true);
			context.requestInteg(true);
			context.requestCredDeleg(true);
			context.requestAnonymity(false);
		} catch (GSSException | NullPointerException e) {
			close(true);
			if (log.isDebugEnabled()) {
				log.debug(format(SshdText.get().gssapiInitFailure,
						currentMechanism.toString()));
			}
			currentMechanism = null;
			state = ProtocolState.FAILED;
			return false;
		}
		Buffer buffer = session
				.createBuffer(SshConstants.SSH_MSG_USERAUTH_REQUEST);
		buffer.putString(session.getUsername());
		buffer.putString(service);
		buffer.putString(getName());
		buffer.putInt(1);
		buffer.putBytes(currentMechanism.getDER());
		session.writePacket(buffer);
		return true;
	}

	@Override
	protected boolean processAuthDataRequest(ClientSession session,
			String service, Buffer in) throws Exception {
		// SSH_MSG_USERAUTH_FAILURE and SSH_MSG_USERAUTH_SUCCESS, as well as
		// SSH_MSG_USERAUTH_BANNER are handled by the framework.
		int command = in.getUByte();
		if (context == null) {
			return false;
		}
		try {
			switch (command) {
			case SSH_MSG_USERAUTH_GSSAPI_RESPONSE: {
				if (state != ProtocolState.STARTED) {
					return unexpectedMessage(command);
				}
				// Initial reply from the server with the mechanism to use.
				Oid mechanism = new Oid(in.getBytes());
				if (!currentMechanism.equals(mechanism)) {
					return false;
				}
				replyToken(session, service, new byte[0]);
				return true;
			}
			case SSH_MSG_USERAUTH_GSSAPI_TOKEN: {
				if (context.isEstablished() || state != ProtocolState.TOKENS) {
					return unexpectedMessage(command);
				}
				// Server sent us a token
				replyToken(session, service, in.getBytes());
				return true;
			}
			default:
				return unexpectedMessage(command);
			}
		} catch (GSSException e) {
			log.warn(format(SshdText.get().gssapiFailure,
					currentMechanism.toString()), e);
			state = ProtocolState.FAILED;
			return false;
		}
	}

	@Override
	public void destroy() {
		try {
			close(false);
		} finally {
			super.destroy();
		}
	}

	private void close(boolean silent) {
		try {
			if (context != null) {
				context.dispose();
				context = null;
			}
		} catch (GSSException e) {
			if (!silent) {
				log.warn(SshdText.get().gssapiFailure, e);
			}
		}
	}

	private void sendToken(ClientSession session, byte[] receivedToken)
			throws IOException, GSSException {
		state = ProtocolState.TOKENS;
		byte[] token = context.initSecContext(receivedToken, 0,
				receivedToken.length);
		if (token != null) {
			Buffer buffer = session.createBuffer(SSH_MSG_USERAUTH_GSSAPI_TOKEN);
			buffer.putBytes(token);
			session.writePacket(buffer);
		}
	}

	private void sendMic(ClientSession session, String service)
			throws IOException, GSSException {
		state = ProtocolState.MIC_SENT;
		// Produce MIC
		Buffer micBuffer = new ByteArrayBuffer();
		micBuffer.putBytes(session.getSessionId());
		micBuffer.putByte(SshConstants.SSH_MSG_USERAUTH_REQUEST);
		micBuffer.putString(session.getUsername());
		micBuffer.putString(service);
		micBuffer.putString(getName());
		byte[] micBytes = micBuffer.getCompactData();
		byte[] mic = context.getMIC(micBytes, 0, micBytes.length,
				new MessageProp(0, true));
		Buffer buffer = session
				.createBuffer(SshConstants.SSH_MSG_USERAUTH_GSSAPI_MIC);
		buffer.putBytes(mic);
		session.writePacket(buffer);
	}

	private void replyToken(ClientSession session, String service, byte[] bytes)
			throws IOException, GSSException {
		sendToken(session, bytes);
		if (context.isEstablished()) {
			sendMic(session, service);
		}
	}

	private String getHostName(ClientSession session) {
		SocketAddress remote = session.getConnectAddress();
		if (remote instanceof InetSocketAddress) {
			InetAddress address = GssApiMechanisms
					.resolve((InetSocketAddress) remote);
			if (address != null) {
				return address.getCanonicalHostName();
			}
		}
		if (session instanceof JGitClientSession) {
			String hostName = ((JGitClientSession) session).getHostConfigEntry()
					.getHostName();
			try {
				hostName = InetAddress.getByName(hostName)
						.getCanonicalHostName();
			} catch (UnknownHostException e) {
				// Ignore here; try with the non-canonical name
			}
			return hostName;
		}
		throw new IllegalStateException(
				"Wrong session class :" + session.getClass().getName()); //$NON-NLS-1$
	}

	private boolean unexpectedMessage(int command) {
		log.warn(format(SshdText.get().gssapiUnexpectedMessage, getName(),
				Integer.toString(command)));
		return false;
	}

}
