/*
 * Author: Tatu Ylonen <ylo@cs.hut.fi>
 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 *                    All rights reserved
 * Created: Fri Mar 17 17:09:28 1995 ylo
 * This program is the ssh daemon.  It listens for connections from clients, and
 * performs authentication, executes use commands or shell, and forwards
 * information to/from the application to the user client over an encrypted
 * connection.  This can also handle forwarding of X11, TCP/IP, and authentication
 * agent connections.
 *
 * SSH2 implementation,
 * Copyright (c) 2000 Markus Friedl. All rights reserved.
 */

#include "includes.h"
RCSID("$OpenBSD: sshd.c,v 1.119 2000/06/22 16:32:27 markus Exp $");

#include "xmalloc.h"
#include "rsa.h"
#include "ssh.h"
#include "pty.h"
#include "packet.h"
#include "cipher.h"
#include "mpaux.h"
#include "servconf.h"
#include "uidswap.h"
#include "compat.h"
#include "buffer.h"

#include "ssh2.h"
#include <openssl/dh.h>
#include <openssl/bn.h>
#include <openssl/hmac.h>
#include "kex.h"
#include <openssl/dsa.h>
#include <openssl/rsa.h>
#include "key.h"
#include "dsa.h"

#include "auth.h"
#include "myproposal.h"
#include "authfile.h"

#ifdef LIBWRAP
#include <tcpd.h>
#include <syslog.h>
int allow_severity = LOG_INFO;
int deny_severity = LOG_WARNING;
#endif /* LIBWRAP */

#ifndef O_NOCTTY
#define O_NOCTTY	0
#endif

/* Server configuration options. */
ServerOptions options;

/* Name of the server configuration file. */
char *config_file_name = SERVER_CONFIG_FILE;

/*
 * Flag indicating whether IPv4 or IPv6.  This can be set on the command line.
 * Default value is AF_UNSPEC means both IPv4 and IPv6.
 */
#ifdef IPV4_DEFAULT
int IPv4or6 = AF_INET;
#else
int IPv4or6 = AF_UNSPEC;
#endif

/*
 * Debug mode flag.  This can be set on the command line.  If debug
 * mode is enabled, extra debugging output will be sent to the system
 * log, the daemon will not go to background, and will exit after processing
 * the first connection.
 */
int debug_flag = 0;

/* Flag indicating that the daemon is being started from inetd. */
int inetd_flag = 0;

/* debug goes to stderr unless inetd_flag is set */
int log_stderr = 0;

/* argv[0] without path. */
char *av0;

/* Saved arguments to main(). */
char **saved_argv;
int saved_argc;

/*
 * The sockets that the server is listening; this is used in the SIGHUP
 * signal handler.
 */
#define	MAX_LISTEN_SOCKS	16
int listen_socks[MAX_LISTEN_SOCKS];
int num_listen_socks = 0;

/*
 * the client's version string, passed by sshd2 in compat mode. if != NULL,
 * sshd will skip the version-number exchange
 */
char *client_version_string = NULL;
char *server_version_string = NULL;

/*
 * Any really sensitive data in the application is contained in this
 * structure. The idea is that this structure could be locked into memory so
 * that the pages do not get written into swap.  However, there are some
 * problems. The private key contains BIGNUMs, and we do not (in principle)
 * have access to the internals of them, and locking just the structure is
 * not very useful.  Currently, memory locking is not implemented.
 */
struct {
	RSA *private_key;	 /* Private part of empheral server key. */
	RSA *host_key;		 /* Private part of host key. */
	Key *dsa_host_key;       /* Private DSA host key. */
} sensitive_data;

/*
 * Flag indicating whether the current session key has been used.  This flag
 * is set whenever the key is used, and cleared when the key is regenerated.
 */
int key_used = 0;

/* This is set to true when SIGHUP is received. */
int received_sighup = 0;

/* Public side of the server key.  This value is regenerated regularly with
   the private key. */
RSA *public_key;

/* session identifier, used by RSA-auth */
unsigned char session_id[16];

/* same for ssh2 */
unsigned char *session_id2 = NULL;
int session_id2_len = 0;

/* Prototypes for various functions defined later in this file. */
void do_ssh1_kex();
void do_ssh2_kex();

/*
 * Close all listening sockets
 */
void
close_listen_socks(void)
{
	int i;
	for (i = 0; i < num_listen_socks; i++)
		close(listen_socks[i]);
	num_listen_socks = -1;
}

/*
 * Signal handler for SIGHUP.  Sshd execs itself when it receives SIGHUP;
 * the effect is to reread the configuration file (and to regenerate
 * the server key).
 */
void
sighup_handler(int sig)
{
	received_sighup = 1;
	signal(SIGHUP, sighup_handler);
}

/*
 * Called from the main program after receiving SIGHUP.
 * Restarts the server.
 */
void
sighup_restart()
{
	log("Received SIGHUP; restarting.");
	close_listen_socks();
	execv(saved_argv[0], saved_argv);
	log("RESTART FAILED: av0='%s', error: %s.", av0, strerror(errno));
	exit(1);
}

/*
 * Generic signal handler for terminating signals in the master daemon.
 * These close the listen socket; not closing it seems to cause "Address
 * already in use" problems on some machines, which is inconvenient.
 */
void
sigterm_handler(int sig)
{
	log("Received signal %d; terminating.", sig);
	close_listen_socks();
	unlink(options.pid_file);
	exit(255);
}

/*
 * SIGCHLD handler.  This is called whenever a child dies.  This will then
 * reap any zombies left by exited c.
 */
void
main_sigchld_handler(int sig)
{
	int save_errno = errno;
	int status;

	while (waitpid(-1, &status, WNOHANG) > 0)
		;

	signal(SIGCHLD, main_sigchld_handler);
	errno = save_errno;
}

/*
 * Signal handler for the alarm after the login grace period has expired.
 */
void
grace_alarm_handler(int sig)
{
	/* Close the connection. */
	packet_close();

	/* Log error and exit. */
	fatal("Timeout before authentication for %s.", get_remote_ipaddr());
}

/*
 * Signal handler for the key regeneration alarm.  Note that this
 * alarm only occurs in the daemon waiting for connections, and it does not
 * do anything with the private key or random state before forking.
 * Thus there should be no concurrency control/asynchronous execution
 * problems.
 */
/* XXX do we really want this work to be done in a signal handler ? -m */
void
key_regeneration_alarm(int sig)
{
	int save_errno = errno;

	/* Check if we should generate a new key. */
	if (key_used) {
		/* This should really be done in the background. */
		log("Generating new %d bit RSA key.", options.server_key_bits);

		if (sensitive_data.private_key != NULL)
			RSA_free(sensitive_data.private_key);
		sensitive_data.private_key = RSA_new();

		if (public_key != NULL)
			RSA_free(public_key);
		public_key = RSA_new();

		rsa_generate_key(sensitive_data.private_key, public_key,
				 options.server_key_bits);
		arc4random_stir();
		key_used = 0;
		log("RSA key generation complete.");
	}
	/* Reschedule the alarm. */
	signal(SIGALRM, key_regeneration_alarm);
	alarm(options.key_regeneration_time);
	errno = save_errno;
}

void
sshd_exchange_identification(int sock_in, int sock_out)
{
	int i, mismatch;
	int remote_major, remote_minor;
	int major, minor;
	char *s;
	char buf[256];			/* Must not be larger than remote_version. */
	char remote_version[256];	/* Must be at least as big as buf. */

	if ((options.protocol & SSH_PROTO_1) &&
	    (options.protocol & SSH_PROTO_2)) {
		major = PROTOCOL_MAJOR_1;
		minor = 99;
	} else if (options.protocol & SSH_PROTO_2) {
		major = PROTOCOL_MAJOR_2;
		minor = PROTOCOL_MINOR_2;
	} else {
		major = PROTOCOL_MAJOR_1;
		minor = PROTOCOL_MINOR_1;
	}
	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
	server_version_string = xstrdup(buf);

	if (client_version_string == NULL) {
		/* Send our protocol version identification. */
		if (atomicio(write, sock_out, server_version_string, strlen(server_version_string))
		    != strlen(server_version_string)) {
			log("Could not write ident string to %s.", get_remote_ipaddr());
			fatal_cleanup();
		}

		/* Read other side\'s version identification. */
		for (i = 0; i < sizeof(buf) - 1; i++) {
			if (atomicio(read, sock_in, &buf[i], 1) != 1) {
				log("Did not receive ident string from %s.", get_remote_ipaddr());
				fatal_cleanup();
			}
			if (buf[i] == '\r') {
				buf[i] = '\n';
				buf[i + 1] = 0;
				continue;
			}
			if (buf[i] == '\n') {
				/* buf[i] == '\n' */
				buf[i + 1] = 0;
				break;
			}
		}
		buf[sizeof(buf) - 1] = 0;
		client_version_string = xstrdup(buf);
	}

	/*
	 * Check that the versions match.  In future this might accept
	 * several versions and set appropriate flags to handle them.
	 */
	if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n",
	    &remote_major, &remote_minor, remote_version) != 3) {
		s = "Protocol mismatch.\n";
		(void) atomicio(write, sock_out, s, strlen(s));
		close(sock_in);
		close(sock_out);
		log("Bad protocol version identification '%.100s' from %s",
		    client_version_string, get_remote_ipaddr());
		fatal_cleanup();
	}
	debug("Client protocol version %d.%d; client software version %.100s",
	      remote_major, remote_minor, remote_version);

	compat_datafellows(remote_version);

	mismatch = 0;
	switch(remote_major) {
	case 1:
		if (remote_minor == 99) {
			if (options.protocol & SSH_PROTO_2)
				enable_compat20();
			else
				mismatch = 1;
			break;
		}
		if (!(options.protocol & SSH_PROTO_1)) {
			mismatch = 1;
			break;
		}
		if (remote_minor < 3) {
			packet_disconnect("Your ssh version is too old and"
			    "is no longer supported.  Please install a newer version.");
		} else if (remote_minor == 3) {
			/* note that this disables agent-forwarding */
			enable_compat13();
		}
		break;
	case 2:
		if (options.protocol & SSH_PROTO_2) {
			enable_compat20();
			break;
		}
		/* FALLTHROUGH */
	default:
		mismatch = 1;
		break;
	}
	chop(server_version_string);
	chop(client_version_string);
	debug("Local version string %.200s", server_version_string);

	if (mismatch) {
		s = "Protocol major versions differ.\n";
		(void) atomicio(write, sock_out, s, strlen(s));
		close(sock_in);
		close(sock_out);
		log("Protocol major versions differ for %s: %.200s vs. %.200s",
		    get_remote_ipaddr(),
		    server_version_string, client_version_string);
		fatal_cleanup();
	}
	if (compat20)
		packet_set_ssh2_format();
}


void
destroy_sensitive_data(void)
{
	/* Destroy the private and public keys.  They will no longer be needed. */
	if (public_key)
		RSA_free(public_key);
	if (sensitive_data.private_key)
		RSA_free(sensitive_data.private_key);
	if (sensitive_data.host_key)
		RSA_free(sensitive_data.host_key);
	if (sensitive_data.dsa_host_key != NULL)
		key_free(sensitive_data.dsa_host_key);
}

/*
 * Main program for the daemon.
 */
int
main(int ac, char **av)
{
	extern char *optarg;
	extern int optind;
	int opt, sock_in = 0, sock_out = 0, newsock, i, fdsetsz, on = 1;
	pid_t pid;
	socklen_t fromlen;
	int silent = 0;
	fd_set *fdset;
	struct sockaddr_storage from;
	const char *remote_ip;
	int remote_port;
	FILE *f;
	struct linger linger;
	struct addrinfo *ai;
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
	int listen_sock, maxfd;

	init_rng();

	/* Save argv[0]. */
	saved_argc = ac;
	saved_argv = av;
	if (strchr(av[0], '/'))
		av0 = strrchr(av[0], '/') + 1;
	else
		av0 = av[0];

	/* Initialize configuration options to their default values. */
	initialize_server_options(&options);

	/* Parse command-line arguments. */
	while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ46")) != EOF) {
		switch (opt) {
		case '4':
			IPv4or6 = AF_INET;
			break;
		case '6':
			IPv4or6 = AF_INET6;
			break;
		case 'f':
			config_file_name = optarg;
			break;
		case 'd':
			debug_flag = 1;
			options.log_level = SYSLOG_LEVEL_DEBUG;
			break;
		case 'i':
			inetd_flag = 1;
			break;
		case 'Q':
			silent = 1;
			break;
		case 'q':
			options.log_level = SYSLOG_LEVEL_QUIET;
			break;
		case 'b':
			options.server_key_bits = atoi(optarg);
			break;
		case 'p':
			options.ports_from_cmdline = 1;
			if (options.num_ports >= MAX_PORTS)
				fatal("too many ports.\n");
			options.ports[options.num_ports++] = atoi(optarg);
			break;
		case 'g':
			options.login_grace_time = atoi(optarg);
			break;
		case 'k':
			options.key_regeneration_time = atoi(optarg);
			break;
		case 'h':
			options.host_key_file = optarg;
			break;
		case 'V':
			client_version_string = optarg;
			/* only makes sense with inetd_flag, i.e. no listen() */
			inetd_flag = 1;
			break;
		case '?':
		default:
			fprintf(stderr, "sshd version %s\n", SSH_VERSION);
			fprintf(stderr, "Usage: %s [options]\n", av0);
			fprintf(stderr, "Options:\n");
			fprintf(stderr, "  -f file    Configuration file (default %s)\n", SERVER_CONFIG_FILE);
			fprintf(stderr, "  -d         Debugging mode\n");
			fprintf(stderr, "  -i         Started from inetd\n");
			fprintf(stderr, "  -q         Quiet (no logging)\n");
			fprintf(stderr, "  -p port    Listen on the specified port (default: 22)\n");
			fprintf(stderr, "  -k seconds Regenerate server key every this many seconds (default: 3600)\n");
			fprintf(stderr, "  -g seconds Grace period for authentication (default: 300)\n");
			fprintf(stderr, "  -b bits    Size of server RSA key (default: 768 bits)\n");
			fprintf(stderr, "  -h file    File from which to read host key (default: %s)\n",
			    HOST_KEY_FILE);
			fprintf(stderr, "  -4         Use IPv4 only\n");
			fprintf(stderr, "  -6         Use IPv6 only\n");
			exit(1);
		}
	}

	/*
	 * Force logging to stderr until we have loaded the private host
	 * key (unless started from inetd)
	 */
	log_init(av0,
	    options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
	    options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility,
	    !silent && !inetd_flag);

	/* Read server configuration options from the configuration file. */
	read_server_config(&options, config_file_name);

	/* Fill in default values for those options not explicitly set. */
	fill_default_server_options(&options);

	/* Check that there are no remaining arguments. */
	if (optind < ac) {
		fprintf(stderr, "Extra argument %s.\n", av[optind]);
		exit(1);
	}

	debug("sshd version %.100s", SSH_VERSION);

	sensitive_data.dsa_host_key = NULL;
	sensitive_data.host_key = NULL;

	/* check if RSA support exists */
	if ((options.protocol & SSH_PROTO_1) &&
	    rsa_alive() == 0) {
		log("no RSA support in libssl and libcrypto.  See ssl(8)");
		log("Disabling protocol version 1");
		options.protocol &= ~SSH_PROTO_1;
	}
	/* Load the RSA/DSA host key.  It must have empty passphrase. */
	if (options.protocol & SSH_PROTO_1) {
		Key k;
		sensitive_data.host_key = RSA_new();
		k.type = KEY_RSA;
		k.rsa = sensitive_data.host_key;
		errno = 0;
		if (!load_private_key(options.host_key_file, "", &k, NULL)) {
			error("Could not load host key: %.200s: %.100s",
			    options.host_key_file, strerror(errno));
			log("Disabling protocol version 1");
			options.protocol &= ~SSH_PROTO_1;
		}
		k.rsa = NULL;
	}
	if (options.protocol & SSH_PROTO_2) {
		sensitive_data.dsa_host_key = key_new(KEY_DSA);
		if (!load_private_key(options.host_dsa_key_file, "", sensitive_data.dsa_host_key, NULL)) {

			error("Could not load DSA host key: %.200s", options.host_dsa_key_file);
			log("Disabling protocol version 2");
			options.protocol &= ~SSH_PROTO_2;
		}
	}
	if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) {
		if (silent == 0)
			fprintf(stderr, "sshd: no hostkeys available -- exiting.\n");
		log("sshd: no hostkeys available -- exiting.\n");
		exit(1);
	}

	/* Check certain values for sanity. */
	if (options.protocol & SSH_PROTO_1) {
		if (options.server_key_bits < 512 ||
		    options.server_key_bits > 32768) {
			fprintf(stderr, "Bad server key size.\n");
			exit(1);
		}
		/*
		 * Check that server and host key lengths differ sufficiently. This
		 * is necessary to make double encryption work with rsaref. Oh, I
		 * hate software patents. I dont know if this can go? Niels
		 */
		if (options.server_key_bits >
		    BN_num_bits(sensitive_data.host_key->n) - SSH_KEY_BITS_RESERVED &&
		    options.server_key_bits <
		    BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) {
			options.server_key_bits =
			    BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED;
			debug("Forcing server key to %d bits to make it differ from host key.",
			    options.server_key_bits);
		}
	}

	/* Initialize the log (it is reinitialized below in case we forked). */
	if (debug_flag && !inetd_flag)
		log_stderr = 1;
	log_init(av0, options.log_level, options.log_facility, log_stderr);

	/*
	 * If not in debugging mode, and not started from inetd, disconnect
	 * from the controlling terminal, and fork.  The original process
	 * exits.
	 */
	if (!debug_flag && !inetd_flag) {
#ifdef TIOCNOTTY
		int fd;
#endif /* TIOCNOTTY */
		if (daemon(0, 0) < 0)
			fatal("daemon() failed: %.200s", strerror(errno));

		/* Disconnect from the controlling tty. */
#ifdef TIOCNOTTY
		fd = open("/dev/tty", O_RDWR | O_NOCTTY);
		if (fd >= 0) {
			(void) ioctl(fd, TIOCNOTTY, NULL);
			close(fd);
		}
#endif /* TIOCNOTTY */
	}
	/* Reinitialize the log (because of the fork above). */
	log_init(av0, options.log_level, options.log_facility, log_stderr);

	/* Do not display messages to stdout in RSA code. */
	rsa_set_verbose(0);

	/* Initialize the random number generator. */
	arc4random_stir();

	/* Chdir to the root directory so that the current disk can be
	   unmounted if desired. */
	chdir("/");

	/* Start listening for a socket, unless started from inetd. */
	if (inetd_flag) {
		int s1, s2;
		s1 = dup(0);	/* Make sure descriptors 0, 1, and 2 are in use. */
		s2 = dup(s1);
		sock_in = dup(0);
		sock_out = dup(1);
		/*
		 * We intentionally do not close the descriptors 0, 1, and 2
		 * as our code for setting the descriptors won\'t work if
		 * ttyfd happens to be one of those.
		 */
		debug("inetd sockets after dupping: %d, %d", sock_in, sock_out);

		if (options.protocol & SSH_PROTO_1) {
			public_key = RSA_new();
			sensitive_data.private_key = RSA_new();
			log("Generating %d bit RSA key.", options.server_key_bits);
			rsa_generate_key(sensitive_data.private_key, public_key,
			    options.server_key_bits);
			arc4random_stir();
			log("RSA key generation complete.");
		}
	} else {
		for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
			if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
				continue;
			if (num_listen_socks >= MAX_LISTEN_SOCKS)
				fatal("Too many listen sockets. "
				    "Enlarge MAX_LISTEN_SOCKS");
			if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
			    ntop, sizeof(ntop), strport, sizeof(strport),
			    NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
				error("getnameinfo failed");
				continue;
			}
			/* Create socket for listening. */
			listen_sock = socket(ai->ai_family, SOCK_STREAM, 0);
			if (listen_sock < 0) {
				/* kernel may not support ipv6 */
				verbose("socket: %.100s", strerror(errno));
				continue;
			}
			if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) < 0) {
				error("listen_sock O_NONBLOCK: %s", strerror(errno));
				close(listen_sock);
				continue;
			}
			/*
			 * Set socket options.  We try to make the port
			 * reusable and have it close as fast as possible
			 * without waiting in unnecessary wait states on
			 * close.
			 */
			setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
			    (void *) &on, sizeof(on));
			linger.l_onoff = 1;
			linger.l_linger = 5;
			setsockopt(listen_sock, SOL_SOCKET, SO_LINGER,
			    (void *) &linger, sizeof(linger));

			debug("Bind to port %s on %s.", strport, ntop);

			/* Bind the socket to the desired port. */
			if ((bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) &&
				 (!ai->ai_next)) {
				error("Bind to port %s on %s failed: %.200s.",
				    strport, ntop, strerror(errno));
				close(listen_sock);
				continue;
			}
			listen_socks[num_listen_socks] = listen_sock;
			num_listen_socks++;

			/* Start listening on the port. */
			log("Server listening on %s port %s.", ntop, strport);
			if (listen(listen_sock, 5) < 0)
				fatal("listen: %.100s", strerror(errno));

		}
		freeaddrinfo(options.listen_addrs);

		if (!num_listen_socks)
			fatal("Cannot bind any address.");

		if (!debug_flag) {
			/*
			 * Record our pid in /etc/sshd_pid to make it easier
			 * to kill the correct sshd.  We don\'t want to do
			 * this before the bind above because the bind will
			 * fail if there already is a daemon, and this will
			 * overwrite any old pid in the file.
			 */
			f = fopen(options.pid_file, "w");
			if (f) {
				fprintf(f, "%u\n", (unsigned int) getpid());
				fclose(f);
			}
		}
		if (options.protocol & SSH_PROTO_1) {
			public_key = RSA_new();
			sensitive_data.private_key = RSA_new();

			log("Generating %d bit RSA key.", options.server_key_bits);
			rsa_generate_key(sensitive_data.private_key, public_key,
			    options.server_key_bits);
			arc4random_stir();
			log("RSA key generation complete.");

			/* Schedule server key regeneration alarm. */
			signal(SIGALRM, key_regeneration_alarm);
			alarm(options.key_regeneration_time);
		}

		/* Arrange to restart on SIGHUP.  The handler needs listen_sock. */
		signal(SIGHUP, sighup_handler);
		signal(SIGTERM, sigterm_handler);
		signal(SIGQUIT, sigterm_handler);

		/* Arrange SIGCHLD to be caught. */
		signal(SIGCHLD, main_sigchld_handler);

		/* setup fd set for listen */
		maxfd = 0;
		for (i = 0; i < num_listen_socks; i++)
			if (listen_socks[i] > maxfd)
				maxfd = listen_socks[i];
		fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask);
		fdset = (fd_set *)xmalloc(fdsetsz);

		/*
		 * Stay listening for connections until the system crashes or
		 * the daemon is killed with a signal.
		 */
		for (;;) {
			if (received_sighup)
				sighup_restart();
			/* Wait in select until there is a connection. */
			memset(fdset, 0, fdsetsz);
			for (i = 0; i < num_listen_socks; i++)
				FD_SET(listen_socks[i], fdset);
			if (select(maxfd + 1, fdset, NULL, NULL, NULL) < 0) {
				if (errno != EINTR)
					error("select: %.100s", strerror(errno));
				continue;
			}
			for (i = 0; i < num_listen_socks; i++) {
				if (!FD_ISSET(listen_socks[i], fdset))
					continue;
			fromlen = sizeof(from);
			newsock = accept(listen_socks[i], (struct sockaddr *)&from,
			    &fromlen);
			if (newsock < 0) {
				if (errno != EINTR && errno != EWOULDBLOCK)
					error("accept: %.100s", strerror(errno));
				continue;
			}
			if (fcntl(newsock, F_SETFL, 0) < 0) {
				error("newsock del O_NONBLOCK: %s", strerror(errno));
				continue;
			}
			/*
			 * Got connection.  Fork a child to handle it, unless
			 * we are in debugging mode.
			 */
			if (debug_flag) {
				/*
				 * In debugging mode.  Close the listening
				 * socket, and start processing the
				 * connection without forking.
				 */
				debug("Server will not fork when running in debugging mode.");
				close_listen_socks();
				sock_in = newsock;
				sock_out = newsock;
				pid = getpid();
				break;
			} else {
				/*
				 * Normal production daemon.  Fork, and have
				 * the child process the connection. The
				 * parent continues listening.
				 */
				if ((pid = fork()) == 0) {
					/*
					 * Child.  Close the listening socket, and start using the
					 * accepted socket.  Reinitialize logging (since our pid has
					 * changed).  We break out of the loop to handle the connection.
					 */
					close_listen_socks();
					sock_in = newsock;
					sock_out = newsock;
					log_init(av0, options.log_level, options.log_facility, log_stderr);
					break;
				}
			}

			/* Parent.  Stay in the loop. */
			if (pid < 0)
				error("fork: %.100s", strerror(errno));
			else
				debug("Forked child %d.", pid);

			/* Mark that the key has been used (it was "given" to the child). */
			key_used = 1;

			arc4random_stir();

			/* Close the new socket (the child is now taking care of it). */
			close(newsock);
			} /* for (i = 0; i < num_listen_socks; i++) */
			/* child process check (or debug mode) */
			if (num_listen_socks < 0)
				break;
		}
	}

	/* This is the child processing a new connection. */

	/*
	 * Disable the key regeneration alarm.  We will not regenerate the
	 * key since we are no longer in a position to give it to anyone. We
	 * will not restart on SIGHUP since it no longer makes sense.
	 */
	alarm(0);
	signal(SIGALRM, SIG_DFL);
	signal(SIGHUP, SIG_DFL);
	signal(SIGTERM, SIG_DFL);
	signal(SIGQUIT, SIG_DFL);
	signal(SIGCHLD, SIG_DFL);

	/*
	 * Set socket options for the connection.  We want the socket to
	 * close as fast as possible without waiting for anything.  If the
	 * connection is not a socket, these will do nothing.
	 */
	/* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
	linger.l_onoff = 1;
	linger.l_linger = 5;
	setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));

	/*
	 * Register our connection.  This turns encryption off because we do
	 * not have a key.
	 */
	packet_set_connection(sock_in, sock_out);

	remote_port = get_remote_port();
	remote_ip = get_remote_ipaddr();

	/* Check whether logins are denied from this host. */
#ifdef LIBWRAP
	/* XXX LIBWRAP noes not know about IPv6 */
	{
		struct request_info req;

		request_init(&req, RQ_DAEMON, av0, RQ_FILE, sock_in, NULL);
		fromhost(&req);

		if (!hosts_access(&req)) {
			close(sock_in);
			close(sock_out);
			refuse(&req);
		}
/*XXX IPv6 verbose("Connection from %.500s port %d", eval_client(&req), remote_port); */
	}
#endif /* LIBWRAP */
	/* Log the connection. */
	verbose("Connection from %.500s port %d", remote_ip, remote_port);

	/*
	 * We don\'t want to listen forever unless the other side
	 * successfully authenticates itself.  So we set up an alarm which is
	 * cleared after successful authentication.  A limit of zero
	 * indicates no limit. Note that we don\'t set the alarm in debugging
	 * mode; it is just annoying to have the server exit just when you
	 * are about to discover the bug.
	 */
	signal(SIGALRM, grace_alarm_handler);
	if (!debug_flag)
		alarm(options.login_grace_time);

	sshd_exchange_identification(sock_in, sock_out);
	/*
	 * Check that the connection comes from a privileged port.  Rhosts-
	 * and Rhosts-RSA-Authentication only make sense from priviledged
	 * programs.  Of course, if the intruder has root access on his local
	 * machine, he can connect from any port.  So do not use these
	 * authentication methods from machines that you do not trust.
	 */
	if (remote_port >= IPPORT_RESERVED ||
	    remote_port < IPPORT_RESERVED / 2) {
		options.rhosts_authentication = 0;
		options.rhosts_rsa_authentication = 0;
	}
#ifdef KRB4
	if (!packet_connection_is_ipv4() &&
	    options.kerberos_authentication) {
		debug("Kerberos Authentication disabled, only available for IPv4.");
		options.kerberos_authentication = 0;
	}
#endif /* KRB4 */

	packet_set_nonblocking();

	/* perform the key exchange */
	/* authenticate user and start session */
	if (compat20) {
		do_ssh2_kex();
		do_authentication2();
	} else {
		do_ssh1_kex();
		do_authentication();
	}

#ifdef KRB4
	/* Cleanup user's ticket cache file. */
	if (options.kerberos_ticket_cleanup)
		(void) dest_tkt();
#endif /* KRB4 */

	/* The connection has been terminated. */
	verbose("Closing connection to %.100s", remote_ip);

#ifdef USE_PAM
	finish_pam();
#endif /* USE_PAM */

	packet_close();
	exit(0);
}

/*
 * SSH1 key exchange
 */
void
do_ssh1_kex()
{
	int i, len;
	int plen, slen;
	BIGNUM *session_key_int;
	unsigned char session_key[SSH_SESSION_KEY_LENGTH];
	unsigned char cookie[8];
	unsigned int cipher_type, auth_mask, protocol_flags;
	u_int32_t rand = 0;

	/*
	 * Generate check bytes that the client must send back in the user
	 * packet in order for it to be accepted; this is used to defy ip
	 * spoofing attacks.  Note that this only works against somebody
	 * doing IP spoofing from a remote machine; any machine on the local
	 * network can still see outgoing packets and catch the random
	 * cookie.  This only affects rhosts authentication, and this is one
	 * of the reasons why it is inherently insecure.
	 */
	for (i = 0; i < 8; i++) {
		if (i % 4 == 0)
			rand = arc4random();
		cookie[i] = rand & 0xff;
		rand >>= 8;
	}

	/*
	 * Send our public key.  We include in the packet 64 bits of random
	 * data that must be matched in the reply in order to prevent IP
	 * spoofing.
	 */
	packet_start(SSH_SMSG_PUBLIC_KEY);
	for (i = 0; i < 8; i++)
		packet_put_char(cookie[i]);

	/* Store our public server RSA key. */
	packet_put_int(BN_num_bits(public_key->n));
	packet_put_bignum(public_key->e);
	packet_put_bignum(public_key->n);

	/* Store our public host RSA key. */
	packet_put_int(BN_num_bits(sensitive_data.host_key->n));
	packet_put_bignum(sensitive_data.host_key->e);
	packet_put_bignum(sensitive_data.host_key->n);

	/* Put protocol flags. */
	packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN);

	/* Declare which ciphers we support. */
	packet_put_int(cipher_mask1());

	/* Declare supported authentication types. */
	auth_mask = 0;
	if (options.rhosts_authentication)
		auth_mask |= 1 << SSH_AUTH_RHOSTS;
	if (options.rhosts_rsa_authentication)
		auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
	if (options.rsa_authentication)
		auth_mask |= 1 << SSH_AUTH_RSA;
#ifdef KRB4
	if (options.kerberos_authentication)
		auth_mask |= 1 << SSH_AUTH_KERBEROS;
#endif
#ifdef AFS
	if (options.kerberos_tgt_passing)
		auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
	if (options.afs_token_passing)
		auth_mask |= 1 << SSH_PASS_AFS_TOKEN;
#endif
#ifdef SKEY
	if (options.skey_authentication == 1)
		auth_mask |= 1 << SSH_AUTH_TIS;
#endif
	if (options.password_authentication)
		auth_mask |= 1 << SSH_AUTH_PASSWORD;
	packet_put_int(auth_mask);

	/* Send the packet and wait for it to be sent. */
	packet_send();
	packet_write_wait();

	debug("Sent %d bit public key and %d bit host key.",
	      BN_num_bits(public_key->n), BN_num_bits(sensitive_data.host_key->n));

	/* Read clients reply (cipher type and session key). */
	packet_read_expect(&plen, SSH_CMSG_SESSION_KEY);

	/* Get cipher type and check whether we accept this. */
	cipher_type = packet_get_char();

	if (!(cipher_mask() & (1 << cipher_type)))
		packet_disconnect("Warning: client selects unsupported cipher.");

	/* Get check bytes from the packet.  These must match those we
	   sent earlier with the public key packet. */
	for (i = 0; i < 8; i++)
		if (cookie[i] != packet_get_char())
			packet_disconnect("IP Spoofing check bytes do not match.");

	debug("Encryption type: %.200s", cipher_name(cipher_type));

	/* Get the encrypted integer. */
	session_key_int = BN_new();
	packet_get_bignum(session_key_int, &slen);

	protocol_flags = packet_get_int();
	packet_set_protocol_flags(protocol_flags);

	packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY);

	/*
	 * Decrypt it using our private server key and private host key (key
	 * with larger modulus first).
	 */
	if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) {
		/* Private key has bigger modulus. */
		if (BN_num_bits(sensitive_data.private_key->n) <
		    BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) {
			fatal("do_connection: %s: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
			      get_remote_ipaddr(),
			      BN_num_bits(sensitive_data.private_key->n),
			      BN_num_bits(sensitive_data.host_key->n),
			      SSH_KEY_BITS_RESERVED);
		}
		rsa_private_decrypt(session_key_int, session_key_int,
				    sensitive_data.private_key);
		rsa_private_decrypt(session_key_int, session_key_int,
				    sensitive_data.host_key);
	} else {
		/* Host key has bigger modulus (or they are equal). */
		if (BN_num_bits(sensitive_data.host_key->n) <
		    BN_num_bits(sensitive_data.private_key->n) + SSH_KEY_BITS_RESERVED) {
			fatal("do_connection: %s: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d",
			      get_remote_ipaddr(),
			      BN_num_bits(sensitive_data.host_key->n),
			      BN_num_bits(sensitive_data.private_key->n),
			      SSH_KEY_BITS_RESERVED);
		}
		rsa_private_decrypt(session_key_int, session_key_int,
				    sensitive_data.host_key);
		rsa_private_decrypt(session_key_int, session_key_int,
				    sensitive_data.private_key);
	}

	compute_session_id(session_id, cookie,
			   sensitive_data.host_key->n,
			   sensitive_data.private_key->n);

	/* Destroy the private and public keys.  They will no longer be needed. */
	destroy_sensitive_data();

	/*
	 * Extract session key from the decrypted integer.  The key is in the
	 * least significant 256 bits of the integer; the first byte of the
	 * key is in the highest bits.
	 */
	BN_mask_bits(session_key_int, sizeof(session_key) * 8);
	len = BN_num_bytes(session_key_int);
	if (len < 0 || len > sizeof(session_key))
		fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d",
		      get_remote_ipaddr(),
		      len, sizeof(session_key));
	memset(session_key, 0, sizeof(session_key));
	BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len);

	/* Destroy the decrypted integer.  It is no longer needed. */
	BN_clear_free(session_key_int);

	/* Xor the first 16 bytes of the session key with the session id. */
	for (i = 0; i < 16; i++)
		session_key[i] ^= session_id[i];

	/* Set the session key.  From this on all communications will be encrypted. */
	packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type);

	/* Destroy our copy of the session key.  It is no longer needed. */
	memset(session_key, 0, sizeof(session_key));

	debug("Received session key; encryption turned on.");

	/* Send an acknowledgement packet.  Note that this packet is sent encrypted. */
	packet_start(SSH_SMSG_SUCCESS);
	packet_send();
	packet_write_wait();
}

/*
 * SSH2 key exchange: diffie-hellman-group1-sha1
 */
void
do_ssh2_kex()
{
	Buffer *server_kexinit;
	Buffer *client_kexinit;
	int payload_len, dlen;
	int slen;
	unsigned int klen, kout;
	unsigned char *signature = NULL;
	unsigned char *server_host_key_blob = NULL;
	unsigned int sbloblen;
	DH *dh;
	BIGNUM *dh_client_pub = 0;
	BIGNUM *shared_secret = 0;
	int i;
	unsigned char *kbuf;
	unsigned char *hash;
	Kex *kex;
	char *cprop[PROPOSAL_MAX];

/* KEXINIT */

	if (options.ciphers != NULL) {
		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
	}
	server_kexinit = kex_init(myproposal);
	client_kexinit = xmalloc(sizeof(*client_kexinit));
	buffer_init(client_kexinit);

	/* algorithm negotiation */
	kex_exchange_kexinit(server_kexinit, client_kexinit, cprop);
	kex = kex_choose_conf(cprop, myproposal, 1);
	for (i = 0; i < PROPOSAL_MAX; i++)
		xfree(cprop[i]);

/* KEXDH */

	debug("Wait SSH2_MSG_KEXDH_INIT.");
	packet_read_expect(&payload_len, SSH2_MSG_KEXDH_INIT);

	/* key, cert */
	dh_client_pub = BN_new();
	if (dh_client_pub == NULL)
		fatal("dh_client_pub == NULL");
	packet_get_bignum2(dh_client_pub, &dlen);

#ifdef DEBUG_KEXDH
	fprintf(stderr, "\ndh_client_pub= ");
	bignum_print(dh_client_pub);
	fprintf(stderr, "\n");
	debug("bits %d", BN_num_bits(dh_client_pub));
#endif

	/* generate DH key */
	dh = dh_new_group1();			/* XXX depends on 'kex' */

#ifdef DEBUG_KEXDH
	fprintf(stderr, "\np= ");
	bignum_print(dh->p);
	fprintf(stderr, "\ng= ");
	bignum_print(dh->g);
	fprintf(stderr, "\npub= ");
	bignum_print(dh->pub_key);
	fprintf(stderr, "\n");
#endif
	if (!dh_pub_is_valid(dh, dh_client_pub))
		packet_disconnect("bad client public DH value");

	klen = DH_size(dh);
	kbuf = xmalloc(klen);
	kout = DH_compute_key(kbuf, dh_client_pub, dh);

#ifdef DEBUG_KEXDH
	debug("shared secret: len %d/%d", klen, kout);
	fprintf(stderr, "shared secret == ");
	for (i = 0; i< kout; i++)
		fprintf(stderr, "%02x", (kbuf[i])&0xff);
	fprintf(stderr, "\n");
#endif
	shared_secret = BN_new();

	BN_bin2bn(kbuf, kout, shared_secret);
	memset(kbuf, 0, klen);
	xfree(kbuf);

	/* XXX precompute? */
	dsa_make_key_blob(sensitive_data.dsa_host_key, &server_host_key_blob, &sbloblen);

	/* calc H */			/* XXX depends on 'kex' */
	hash = kex_hash(
	    client_version_string,
	    server_version_string,
	    buffer_ptr(client_kexinit), buffer_len(client_kexinit),
	    buffer_ptr(server_kexinit), buffer_len(server_kexinit),
	    (char *)server_host_key_blob, sbloblen,
	    dh_client_pub,
	    dh->pub_key,
	    shared_secret
	);
	buffer_free(client_kexinit);
	buffer_free(server_kexinit);
	xfree(client_kexinit);
	xfree(server_kexinit);
#ifdef DEBUG_KEXDH
	fprintf(stderr, "hash == ");
	for (i = 0; i< 20; i++)
		fprintf(stderr, "%02x", (hash[i])&0xff);
	fprintf(stderr, "\n");
#endif
	/* save session id := H */
	/* XXX hashlen depends on KEX */
	session_id2_len = 20;
	session_id2 = xmalloc(session_id2_len);
	memcpy(session_id2, hash, session_id2_len);

	/* sign H */
	/* XXX hashlen depends on KEX */
	dsa_sign(sensitive_data.dsa_host_key, &signature, &slen, hash, 20);

	destroy_sensitive_data();

	/* send server hostkey, DH pubkey 'f' and singed H */
	packet_start(SSH2_MSG_KEXDH_REPLY);
	packet_put_string((char *)server_host_key_blob, sbloblen);
	packet_put_bignum2(dh->pub_key);	/* f */
	packet_put_string((char *)signature, slen);
	packet_send();
	xfree(signature);
	xfree(server_host_key_blob);
	packet_write_wait();

	kex_derive_keys(kex, hash, shared_secret);
	packet_set_kex(kex);

	/* have keys, free DH */
	DH_free(dh);

	debug("send SSH2_MSG_NEWKEYS.");
	packet_start(SSH2_MSG_NEWKEYS);
	packet_send();
	packet_write_wait();
	debug("done: send SSH2_MSG_NEWKEYS.");

	debug("Wait SSH2_MSG_NEWKEYS.");
	packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
	debug("GOT SSH2_MSG_NEWKEYS.");

#ifdef DEBUG_KEXDH
	/* send 1st encrypted/maced/compressed message */
	packet_start(SSH2_MSG_IGNORE);
	packet_put_cstring("markus");
	packet_send();
	packet_write_wait();
#endif
	debug("done: KEX2.");
}
