/*
 * Copyright (C) 2016, Mark Ingram <markdingram@gmail.com>
 * Copyright (C) 2009, Constantine Plotnikov <constantine.plotnikov@gmail.com>
 * Copyright (C) 2008-2009, Google Inc.
 * Copyright (C) 2009, Google, Inc.
 * Copyright (C) 2009, JetBrains s.r.o.
 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
 * 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.transport;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.util.FS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jcraft.jsch.ConfigRepository;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

/**
 * The base session factory that loads known hosts and private keys from
 * <code>$HOME/.ssh</code>.
 * <p>
 * This is the default implementation used by JGit and provides most of the
 * compatibility necessary to match OpenSSH, a popular implementation of SSH
 * used by C Git.
 * <p>
 * The factory does not provide UI behavior. Override the method
 * {@link #configure(org.eclipse.jgit.transport.OpenSshConfig.Host, Session)} to
 * supply appropriate {@link com.jcraft.jsch.UserInfo} to the session.
 */
public abstract class JschConfigSessionFactory extends SshSessionFactory {

	private static final Logger LOG = LoggerFactory
			.getLogger(JschConfigSessionFactory.class);

	/**
	 * We use different Jsch instances for hosts that have an IdentityFile
	 * configured in ~/.ssh/config. Jsch by default would cache decrypted keys
	 * only per session, which results in repeated password prompts. Using
	 * different Jsch instances, we can cache the keys on these instances so
	 * that they will be re-used for successive sessions, and thus the user is
	 * prompted for a key password only once while Eclipse runs.
	 */
	private final Map<String, JSch> byIdentityFile = new HashMap<>();

	private JSch defaultJSch;

	private OpenSshConfig config;

	/** {@inheritDoc} */
	@Override
	public synchronized RemoteSession getSession(URIish uri,
			CredentialsProvider credentialsProvider, FS fs, int tms)
			throws TransportException {

		String user = uri.getUser();
		final String pass = uri.getPass();
		String host = uri.getHost();
		int port = uri.getPort();

		try {
			if (config == null)
				config = OpenSshConfig.get(fs);

			final OpenSshConfig.Host hc = config.lookup(host);
			if (port <= 0)
				port = hc.getPort();
			if (user == null)
				user = hc.getUser();

			Session session = createSession(credentialsProvider, fs, user,
					pass, host, port, hc);

			int retries = 0;
			while (!session.isConnected()) {
				try {
					retries++;
					session.connect(tms);
				} catch (JSchException e) {
					session.disconnect();
					session = null;
					// Make sure our known_hosts is not outdated
					knownHosts(getJSch(hc, fs), fs);

					if (isAuthenticationCanceled(e)) {
						throw e;
					} else if (isAuthenticationFailed(e)
							&& credentialsProvider != null) {
						// if authentication failed maybe credentials changed at
						// the remote end therefore reset credentials and retry
						if (retries < 3) {
							credentialsProvider.reset(uri);
							session = createSession(credentialsProvider, fs,
									user, pass, host, port, hc);
						} else
							throw e;
					} else if (retries >= hc.getConnectionAttempts()) {
						throw e;
					} else {
						try {
							Thread.sleep(1000);
							session = createSession(credentialsProvider, fs,
									user, pass, host, port, hc);
						} catch (InterruptedException e1) {
							throw new TransportException(
									JGitText.get().transportSSHRetryInterrupt,
									e1);
						}
					}
				}
			}

			return new JschSession(session, uri);

		} catch (JSchException je) {
			final Throwable c = je.getCause();
			if (c instanceof UnknownHostException) {
				throw new TransportException(uri, JGitText.get().unknownHost,
						je);
			}
			if (c instanceof ConnectException) {
				throw new TransportException(uri, c.getMessage(), je);
			}
			throw new TransportException(uri, je.getMessage(), je);
		}

	}

	private static boolean isAuthenticationFailed(JSchException e) {
		return e.getCause() == null && e.getMessage().equals("Auth fail"); //$NON-NLS-1$
	}

	private static boolean isAuthenticationCanceled(JSchException e) {
		return e.getCause() == null && e.getMessage().equals("Auth cancel"); //$NON-NLS-1$
	}

	// Package visibility for tests
	Session createSession(CredentialsProvider credentialsProvider,
			FS fs, String user, final String pass, String host, int port,
			final OpenSshConfig.Host hc) throws JSchException {
		final Session session = createSession(hc, user, host, port, fs);
		// Jsch will have overridden the explicit user by the one from the SSH
		// config file...
		setUserName(session, user);
		// Jsch will also have overridden the port.
		if (port > 0 && port != session.getPort()) {
			session.setPort(port);
		}
		// We retry already in getSession() method. JSch must not retry
		// on its own.
		session.setConfig("MaxAuthTries", "1"); //$NON-NLS-1$ //$NON-NLS-2$
		if (pass != null)
			session.setPassword(pass);
		final String strictHostKeyCheckingPolicy = hc
				.getStrictHostKeyChecking();
		if (strictHostKeyCheckingPolicy != null)
			session.setConfig("StrictHostKeyChecking", //$NON-NLS-1$
					strictHostKeyCheckingPolicy);
		final String pauth = hc.getPreferredAuthentications();
		if (pauth != null)
			session.setConfig("PreferredAuthentications", pauth); //$NON-NLS-1$
		if (credentialsProvider != null
				&& (!hc.isBatchMode() || !credentialsProvider.isInteractive())) {
			session.setUserInfo(new CredentialsProviderUserInfo(session,
					credentialsProvider));
		}
		configure(hc, session);
		return session;
	}

	private void setUserName(Session session, String userName) {
		// Jsch 0.1.54 picks up the user name from the ssh config, even if an
		// explicit user name was given! We must correct that if ~/.ssh/config
		// has a different user name.
		if (userName == null || userName.isEmpty()
				|| userName.equals(session.getUserName())) {
			return;
		}
		try {
			Class<?>[] parameterTypes = { String.class };
			Method method = Session.class.getDeclaredMethod("setUserName", //$NON-NLS-1$
					parameterTypes);
			method.setAccessible(true);
			method.invoke(session, userName);
		} catch (NullPointerException | IllegalAccessException
				| IllegalArgumentException | InvocationTargetException
				| NoSuchMethodException | SecurityException e) {
			LOG.error(MessageFormat.format(JGitText.get().sshUserNameError,
					userName, session.getUserName()), e);
		}
	}

	/**
	 * Create a new remote session for the requested address.
	 *
	 * @param hc
	 *            host configuration
	 * @param user
	 *            login to authenticate as.
	 * @param host
	 *            server name to connect to.
	 * @param port
	 *            port number of the SSH daemon (typically 22).
	 * @param fs
	 *            the file system abstraction which will be necessary to
	 *            perform certain file system operations.
	 * @return new session instance, but otherwise unconfigured.
	 * @throws com.jcraft.jsch.JSchException
	 *             the session could not be created.
	 */
	protected Session createSession(final OpenSshConfig.Host hc,
			final String user, final String host, final int port, FS fs)
			throws JSchException {
		return getJSch(hc, fs).getSession(user, host, port);
	}

	/**
	 * Provide additional configuration for the JSch instance. This method could
	 * be overridden to supply a preferred
	 * {@link com.jcraft.jsch.IdentityRepository}.
	 *
	 * @param jsch
	 *            jsch instance
	 * @since 4.5
	 */
	protected void configureJSch(JSch jsch) {
		// No additional configuration required.
	}

	/**
	 * Provide additional configuration for the session based on the host
	 * information. This method could be used to supply
	 * {@link com.jcraft.jsch.UserInfo}.
	 *
	 * @param hc
	 *            host configuration
	 * @param session
	 *            session to configure
	 */
	protected abstract void configure(OpenSshConfig.Host hc, Session session);

	/**
	 * Obtain the JSch used to create new sessions.
	 *
	 * @param hc
	 *            host configuration
	 * @param fs
	 *            the file system abstraction which will be necessary to
	 *            perform certain file system operations.
	 * @return the JSch instance to use.
	 * @throws com.jcraft.jsch.JSchException
	 *             the user configuration could not be created.
	 */
	protected JSch getJSch(OpenSshConfig.Host hc, FS fs) throws JSchException {
		if (defaultJSch == null) {
			defaultJSch = createDefaultJSch(fs);
			if (defaultJSch.getConfigRepository() == null) {
				defaultJSch.setConfigRepository(
						new JschBugFixingConfigRepository(config));
			}
			for (Object name : defaultJSch.getIdentityNames())
				byIdentityFile.put((String) name, defaultJSch);
		}

		final File identityFile = hc.getIdentityFile();
		if (identityFile == null)
			return defaultJSch;

		final String identityKey = identityFile.getAbsolutePath();
		JSch jsch = byIdentityFile.get(identityKey);
		if (jsch == null) {
			jsch = new JSch();
			configureJSch(jsch);
			if (jsch.getConfigRepository() == null) {
				jsch.setConfigRepository(defaultJSch.getConfigRepository());
			}
			jsch.setHostKeyRepository(defaultJSch.getHostKeyRepository());
			jsch.addIdentity(identityKey);
			byIdentityFile.put(identityKey, jsch);
		}
		return jsch;
	}

	/**
	 * Create default instance of jsch
	 *
	 * @param fs
	 *            the file system abstraction which will be necessary to perform
	 *            certain file system operations.
	 * @return the new default JSch implementation.
	 * @throws com.jcraft.jsch.JSchException
	 *             known host keys cannot be loaded.
	 */
	protected JSch createDefaultJSch(FS fs) throws JSchException {
		final JSch jsch = new JSch();
		configureJSch(jsch);
		knownHosts(jsch, fs);
		identities(jsch, fs);
		return jsch;
	}

	private static void knownHosts(JSch sch, FS fs) throws JSchException {
		final File home = fs.userHome();
		if (home == null)
			return;
		final File known_hosts = new File(new File(home, ".ssh"), "known_hosts"); //$NON-NLS-1$ //$NON-NLS-2$
		try (FileInputStream in = new FileInputStream(known_hosts)) {
			sch.setKnownHosts(in);
		} catch (FileNotFoundException none) {
			// Oh well. They don't have a known hosts in home.
		} catch (IOException err) {
			// Oh well. They don't have a known hosts in home.
		}
	}

	private static void identities(JSch sch, FS fs) {
		final File home = fs.userHome();
		if (home == null)
			return;
		final File sshdir = new File(home, ".ssh"); //$NON-NLS-1$
		if (sshdir.isDirectory()) {
			loadIdentity(sch, new File(sshdir, "identity")); //$NON-NLS-1$
			loadIdentity(sch, new File(sshdir, "id_rsa")); //$NON-NLS-1$
			loadIdentity(sch, new File(sshdir, "id_dsa")); //$NON-NLS-1$
		}
	}

	private static void loadIdentity(JSch sch, File priv) {
		if (priv.isFile()) {
			try {
				sch.addIdentity(priv.getAbsolutePath());
			} catch (JSchException e) {
				// Instead, pretend the key doesn't exist.
			}
		}
	}

	private static class JschBugFixingConfigRepository
			implements ConfigRepository {

		private final ConfigRepository base;

		public JschBugFixingConfigRepository(ConfigRepository base) {
			this.base = base;
		}

		@Override
		public Config getConfig(String host) {
			return new JschBugFixingConfig(base.getConfig(host));
		}

		/**
		 * A {@link com.jcraft.jsch.ConfigRepository.Config} that transforms
		 * some values from the config file into the format Jsch 0.1.54 expects.
		 * This is a work-around for bugs in Jsch.
		 * <p>
		 * Additionally, this config hides the IdentityFile config entries from
		 * Jsch; we manage those ourselves. Otherwise Jsch would cache passwords
		 * (or rather, decrypted keys) only for a single session, resulting in
		 * multiple password prompts for user operations that use several Jsch
		 * sessions.
		 */
		private static class JschBugFixingConfig implements Config {

			private static final String[] NO_IDENTITIES = {};

			private final Config real;

			public JschBugFixingConfig(Config delegate) {
				real = delegate;
			}

			@Override
			public String getHostname() {
				return real.getHostname();
			}

			@Override
			public String getUser() {
				return real.getUser();
			}

			@Override
			public int getPort() {
				return real.getPort();
			}

			@Override
			public String getValue(String key) {
				String k = key.toUpperCase(Locale.ROOT);
				if ("IDENTITYFILE".equals(k)) { //$NON-NLS-1$
					return null;
				}
				String result = real.getValue(key);
				if (result != null) {
					if ("SERVERALIVEINTERVAL".equals(k) //$NON-NLS-1$
							|| "CONNECTTIMEOUT".equals(k)) { //$NON-NLS-1$
						// These values are in seconds. Jsch 0.1.54 passes them
						// on as is to java.net.Socket.setSoTimeout(), which
						// expects milliseconds. So convert here to
						// milliseconds.
						try {
							int timeout = Integer.parseInt(result);
							result = Long.toString(
									TimeUnit.SECONDS.toMillis(timeout));
						} catch (NumberFormatException e) {
							// Ignore
						}
					}
				}
				return result;
			}

			@Override
			public String[] getValues(String key) {
				String k = key.toUpperCase(Locale.ROOT);
				if ("IDENTITYFILE".equals(k)) { //$NON-NLS-1$
					return NO_IDENTITIES;
				}
				return real.getValues(key);
			}
		}
	}

	/**
	 * Set the {@link OpenSshConfig} to use. Intended for use in tests.
	 *
	 * @param config
	 *            to use
	 */
	void setConfig(OpenSshConfig config) {
		this.config = config;
	}
}
