// Copyright (C) 2008 The Android Open Source Project
//
// 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.

package com.google.gerrit.server.ssh;

import com.google.gerrit.server.GerritServer;
import com.google.gwtjsonrpc.server.XsrfException;
import com.google.gwtorm.client.OrmException;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.apache.sshd.SshServer;
import org.apache.sshd.common.Cipher;
import org.apache.sshd.common.Compression;
import org.apache.sshd.common.KeyExchange;
import org.apache.sshd.common.KeyPairProvider;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.Signature;
import org.apache.sshd.common.cipher.AES128CBC;
import org.apache.sshd.common.cipher.AES192CBC;
import org.apache.sshd.common.cipher.AES256CBC;
import org.apache.sshd.common.cipher.BlowfishCBC;
import org.apache.sshd.common.cipher.CipherNone;
import org.apache.sshd.common.cipher.TripleDESCBC;
import org.apache.sshd.common.compression.CompressionNone;
import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
import org.apache.sshd.common.mac.HMACMD5;
import org.apache.sshd.common.mac.HMACMD596;
import org.apache.sshd.common.mac.HMACSHA1;
import org.apache.sshd.common.mac.HMACSHA196;
import org.apache.sshd.common.random.BouncyCastleRandom;
import org.apache.sshd.common.random.JceRandom;
import org.apache.sshd.common.random.SingletonRandomFactory;
import org.apache.sshd.common.session.AbstractSession;
import org.apache.sshd.common.signature.SignatureDSA;
import org.apache.sshd.common.signature.SignatureRSA;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.server.ServerChannel;
import org.apache.sshd.server.SessionFactory;
import org.apache.sshd.server.UserAuth;
import org.apache.sshd.server.auth.UserAuthPublicKey;
import org.apache.sshd.server.channel.ChannelSession;
import org.apache.sshd.server.kex.DHG1;
import org.apache.sshd.server.kex.DHG14;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spearce.jgit.lib.RepositoryConfig;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * SSH daemon to communicate with Gerrit.
 * <p>
 * Use a Git URL such as <code>ssh://${email}@${host}:${port}/${path}</code>,
 * e.g. <code>ssh://sop@google.com@gerrit.com:8010/tools/gerrit.git</code> to
 * access the SSH daemon itself.
 * <p>
 * Versions of Git before 1.5.3 may require setting the username and port
 * properties in the user's <code>~/.ssh/config</code> file, and using a host
 * alias through a URL such as <code>gerrit-alias:/tools/gerrit.git:
 * <pre>
 * Host gerrit-alias
 *  User sop@google.com
 *  Hostname gerrit.com
 *  Port 8010
 * </pre>
 */
public class GerritSshDaemon extends SshServer {
  private static final int DEFAULT_PORT = 29418;

  private static final Logger log =
      LoggerFactory.getLogger(GerritSshDaemon.class);

  private static GerritSshDaemon sshd;
  private static InetSocketAddress preferredAddress;
  private static Collection<PublicKey> hostKeys = Collections.emptyList();

  public static synchronized void startSshd() throws OrmException,
      XsrfException, SocketException {
    final GerritServer srv = GerritServer.getInstance();
    final GerritSshDaemon daemon = new GerritSshDaemon(srv);
    final String addressList = daemon.addressList();
    try {
      sshd = daemon;
      preferredAddress = null;
      hostKeys = computeHostKeys();

      if (hostKeys.isEmpty()) {
        throw new IOException("No SSHD host key");
      }
      daemon.start();

      log.info("Started Gerrit SSHD on " + addressList);
    } catch (IOException e) {
      sshd = null;
      preferredAddress = null;
      hostKeys = Collections.emptyList();

      final String msg = "Cannot start Gerrit SSHD on " + addressList;
      log.error(msg, e);
      final SocketException e2;
      e2 = new SocketException(msg);
      e2.initCause(e);
      throw e2;
    }
  }

  private static Collection<PublicKey> computeHostKeys() {
    final KeyPairProvider p = sshd.getKeyPairProvider();
    final List<PublicKey> keys = new ArrayList<PublicKey>(2);
    addPublicKey(keys, p, KeyPairProvider.SSH_DSS);
    addPublicKey(keys, p, KeyPairProvider.SSH_RSA);
    return Collections.unmodifiableList(keys);
  }

  private static void addPublicKey(final Collection<PublicKey> out,
      final KeyPairProvider p, final String type) {
    final KeyPair pair = p.loadKey(type);
    if (pair != null && pair.getPublic() != null) {
      out.add(pair.getPublic());
    }
  }

  private static String format(final SocketAddress addr) {
    if (addr instanceof InetSocketAddress) {
      final InetSocketAddress inetAddr = (InetSocketAddress) addr;
      final InetAddress hostAddr = inetAddr.getAddress();
      String host;
      if (hostAddr.isAnyLocalAddress()) {
        host = "*";
      } else {
        host = "[" + hostAddr.getHostName() + "]";
      }
      return host + ":" + inetAddr.getPort();
    }
    return addr.toString();
  }

  public static synchronized void stopSshd() {
    if (sshd != null) {
      try {
        sshd.stop();
        log.info("Stopped Gerrit SSHD");
      } finally {
        sshd = null;
        preferredAddress = null;
        hostKeys = Collections.emptyList();
      }
    }
  }

  public static synchronized IoAcceptor getIoAcceptor() {
    return sshd != null ? sshd.acceptor : null;
  }

  public static synchronized Collection<PublicKey> getHostKeys() {
    return hostKeys;
  }

  public static synchronized InetSocketAddress getAddress() {
    if (sshd != null && preferredAddress == null) {
      preferredAddress = computePreferredAddress();
    }
    return preferredAddress;
  }

  private static InetSocketAddress computePreferredAddress() {
    for (final SocketAddress addr : sshd.listen) {
      if (!(addr instanceof InetSocketAddress)) {
        continue;
      }

      InetSocketAddress inetAddr = (InetSocketAddress) addr;
      if (inetAddr.getAddress().isLoopbackAddress()) {
        continue;
      }
      return inetAddr;
    }
    return null;
  }

  private List<SocketAddress> listen;
  private IoAcceptor acceptor;
  private boolean reuseAddress;
  private boolean keepAlive;

  private GerritSshDaemon(final GerritServer srv) {
    setPort(22/* never used */);

    final RepositoryConfig cfg = srv.getGerritConfig();
    listen = parseListen(cfg);
    reuseAddress = cfg.getBoolean("sshd", "reuseaddress", true);
    keepAlive = cfg.getBoolean("sshd", "tcpkeepalive", true);

    if (SecurityUtils.isBouncyCastleRegistered()) {
      initProviderBouncyCastle();
    } else {
      initProviderJce();
    }
    initCiphers(cfg);
    initMacs(cfg);
    initSignatures();
    initChannels();
    initCompression();
    initUserAuth(srv);
    setKeyPairProvider(initHostKey(srv));
    setCommandFactory(new GerritCommandFactory());
    setShellFactory(new NoShell());
    setSessionFactory(new SessionFactory() {
      @Override
      protected AbstractSession createSession(final IoSession io)
          throws Exception {
        if (io.getConfig() instanceof SocketSessionConfig) {
          final SocketSessionConfig c = (SocketSessionConfig) io.getConfig();
          c.setKeepAlive(keepAlive);
        }

        final AbstractSession s = super.createSession(io);
        s.setAttribute(SshUtil.REMOTE_PEER, io.getRemoteAddress());
        s.setAttribute(SshUtil.ACTIVE, new ArrayList<AbstractCommand>(2));
        return s;
      }
    });
  }

  @Override
  public void start() throws IOException {
    if (acceptor == null) {
      checkConfig();

      final NioSocketAcceptor ain = new NioSocketAcceptor();
      final SessionFactory handler = getSessionFactory();
      handler.setServer(this);
      ain.setHandler(handler);
      ain.setReuseAddress(reuseAddress);
      ain.bind(listen);
      acceptor = ain;
    }
  }

  @Override
  public void stop() {
    if (acceptor != null) {
      try {
        acceptor.dispose();
      } finally {
        acceptor = null;
      }
    }
  }

  private String addressList() {
    final StringBuilder r = new StringBuilder();
    for (Iterator<SocketAddress> i = listen.iterator(); i.hasNext();) {
      r.append(format(i.next()));
      if (i.hasNext()) {
        r.append(", ");
      }
    }
    return r.toString();
  }

  private List<SocketAddress> parseListen(final RepositoryConfig cfg) {
    final ArrayList<SocketAddress> bind = new ArrayList<SocketAddress>(2);
    final String[] want = cfg.getStringList("sshd", null, "listenaddress");
    if (want == null || want.length == 0) {
      bind.add(new InetSocketAddress(DEFAULT_PORT));
      return bind;
    }

    for (final String desc : want) {
      try {
        bind.add(toSocketAddress(desc));
      } catch (IllegalArgumentException e) {
        log.error("Bad sshd.listenaddress: " + desc + ": " + e.getMessage());
      }
    }

    return bind;
  }

  private SocketAddress toSocketAddress(final String desc) {
    String hostStr;
    String portStr;

    if (desc.startsWith("[")) {
      // IPv6, as a raw IP address.
      //
      final int hostEnd = desc.indexOf(']');
      if (hostEnd < 0) {
        throw new IllegalArgumentException("invalid IPv6 representation");
      }

      hostStr = desc.substring(1, hostEnd);
      portStr = desc.substring(hostEnd + 1);
    } else {
      // IPv4, or a host name.
      //
      final int hostEnd = desc.indexOf(':');
      hostStr = 0 <= hostEnd ? desc.substring(0, hostEnd) : desc;
      portStr = 0 <= hostEnd ? desc.substring(hostEnd) : "";
    }

    if ("*".equals(hostStr)) {
      hostStr = "";
    }
    if (portStr.startsWith(":")) {
      portStr = portStr.substring(1);
    }

    final int port;
    if (portStr.length() > 0) {
      try {
        port = Integer.parseInt(portStr);
      } catch (NumberFormatException e) {
        throw new IllegalArgumentException("invalid port");
      }
    } else {
      port = DEFAULT_PORT;
    }

    if (hostStr.length() > 0) {
      try {
        return new InetSocketAddress(InetAddress.getByName(hostStr), port);
      } catch (UnknownHostException e) {
        throw new IllegalArgumentException(e.getMessage(), e);
      }
    } else {
      return new InetSocketAddress(port);
    }
  }

  @SuppressWarnings("unchecked")
  private void initProviderBouncyCastle() {
    setKeyExchangeFactories(Arrays.<NamedFactory<KeyExchange>> asList(
        new DHG14.Factory(), new DHG1.Factory()));
    setRandomFactory(new SingletonRandomFactory(
        new BouncyCastleRandom.Factory()));
  }

  @SuppressWarnings("unchecked")
  private void initProviderJce() {
    setKeyExchangeFactories(Arrays
        .<NamedFactory<KeyExchange>> asList(new DHG1.Factory()));
    setRandomFactory(new SingletonRandomFactory(new JceRandom.Factory()));
  }

  @SuppressWarnings("unchecked")
  private void initCiphers(final RepositoryConfig cfg) {
    final List<NamedFactory<Cipher>> a = new LinkedList<NamedFactory<Cipher>>();
    a.add(new AES128CBC.Factory());
    a.add(new TripleDESCBC.Factory());
    a.add(new BlowfishCBC.Factory());
    a.add(new AES192CBC.Factory());
    a.add(new AES256CBC.Factory());

    for (Iterator<NamedFactory<Cipher>> i = a.iterator(); i.hasNext();) {
      final NamedFactory<Cipher> f = i.next();
      try {
        final Cipher c = f.create();
        final byte[] key = new byte[c.getBlockSize()];
        final byte[] iv = new byte[c.getIVSize()];
        c.init(Cipher.Mode.Encrypt, key, iv);
      } catch (InvalidKeyException e) {
        log.warn("Disabling cipher " + f.getName() + ": " + e.getMessage()
            + "; try installing unlimited cryptography extension");
        i.remove();
      } catch (Exception e) {
        log.warn("Disabling cipher " + f.getName() + ": " + e.getMessage());
        i.remove();
      }
    }

    a.add(null);
    a.add(new CipherNone.Factory());
    setCipherFactories(filter(cfg, "cipher", a.toArray(new NamedFactory[a
        .size()])));
  }

  @SuppressWarnings("unchecked")
  private void initMacs(final RepositoryConfig cfg) {
    setMacFactories(filter(cfg, "mac", new HMACMD5.Factory(),
        new HMACSHA1.Factory(), new HMACMD596.Factory(),
        new HMACSHA196.Factory()));
  }

  private static <T> List<NamedFactory<T>> filter(final RepositoryConfig cfg,
      final String key, final NamedFactory<T>... avail) {
    final ArrayList<NamedFactory<T>> def = new ArrayList<NamedFactory<T>>();
    for (final NamedFactory<T> n : avail) {
      if (n == null) {
        break;
      }
      def.add(n);
    }

    final String[] want = cfg.getStringList("sshd", null, key);
    if (want == null || want.length == 0) {
      return def;
    }

    boolean didClear = false;
    for (final String setting : want) {
      String name = setting.trim();
      boolean add = true;
      if (name.startsWith("-")) {
        add = false;
        name = name.substring(1).trim();
      } else if (name.startsWith("+")) {
        name = name.substring(1).trim();
      } else if (!didClear) {
        didClear = true;
        def.clear();
      }

      final NamedFactory<T> n = find(name, avail);
      if (n == null) {
        final StringBuilder msg = new StringBuilder();
        msg.append("sshd." + key + " = " + name + " unsupported; only ");
        for (int i = 0; i < avail.length; i++) {
          if (avail[i] == null) {
            continue;
          }
          if (i > 0) {
            msg.append(", ");
          }
          msg.append(avail[i].getName());
        }
        msg.append(" is supported");
        log.error(msg.toString());
      } else if (add) {
        if (!def.contains(n)) {
          def.add(n);
        }
      } else {
        def.remove(n);
      }
    }

    return def;
  }

  private static <T> NamedFactory<T> find(final String name,
      final NamedFactory<T>... avail) {
    for (final NamedFactory<T> n : avail) {
      if (n != null && name.equals(n.getName())) {
        return n;
      }
    }
    return null;
  }

  @SuppressWarnings("unchecked")
  private void initSignatures() {
    setSignatureFactories(Arrays.<NamedFactory<Signature>> asList(
        new SignatureDSA.Factory(), new SignatureRSA.Factory()));
  }

  @SuppressWarnings("unchecked")
  private void initCompression() {
    // Always disable transparent compression. The majority of our data
    // transfer is highly compressed Git pack files. We cannot make them
    // any smaller than they already are.
    //
    setCompressionFactories(Arrays
        .<NamedFactory<Compression>> asList(new CompressionNone.Factory()));
  }

  @SuppressWarnings("unchecked")
  private void initChannels() {
    setChannelFactories(Arrays
        .<NamedFactory<ServerChannel>> asList(new ChannelSession.Factory()));
  }

  @SuppressWarnings("unchecked")
  private void initUserAuth(final GerritServer srv) {
    setUserAuthFactories(Arrays
        .<NamedFactory<UserAuth>> asList(new UserAuthPublicKey.Factory()));
    setPublickeyAuthenticator(new DatabasePubKeyAuth(srv));
  }

  private KeyPairProvider initHostKey(final GerritServer srv) {
    final File sitePath = srv.getSitePath();

    final File anyKey = new File(sitePath, "ssh_host_key");
    final File rsaKey = new File(sitePath, "ssh_host_rsa_key");
    final File dsaKey = new File(sitePath, "ssh_host_dsa_key");

    final List<String> keys = new ArrayList<String>(2);
    if (rsaKey.exists()) {
      keys.add(rsaKey.getAbsolutePath());
    }
    if (dsaKey.exists()) {
      keys.add(dsaKey.getAbsolutePath());
    }

    if (anyKey.exists() && !keys.isEmpty()) {
      // If both formats of host key exist, we don't know which format
      // should be authoritative. Complain and abort.
      //
      keys.add(anyKey.getAbsolutePath());
      throw new IllegalStateException("Multiple host keys exist: " + keys);
    }

    if (keys.isEmpty()) {
      // No administrator created host key? Generate and save our own.
      //
      final SimpleGeneratorHostKeyProvider keyp;

      keyp = new SimpleGeneratorHostKeyProvider();
      keyp.setPath(anyKey.getAbsolutePath());
      return keyp;
    }

    return new FileKeyPairProvider(keys.toArray(new String[keys.size()]));
  }
}
