/*
 * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
 *
 * Modification and redistribution in source and binary forms is
 * permitted provided that due credit is given to the author and the
 * OpenBSD project (for instance by leaving this copyright notice
 * intact).
 */

#include "includes.h"
RCSID("$OpenBSD: ssh-keyscan.c,v 1.12 2001/02/04 15:32:26 stevesk Exp $");

#if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H)
#include <sys/queue.h>
#else
#include "fake-queue.h"
#endif
#include <errno.h>

#include <openssl/bn.h>

#include "xmalloc.h"
#include "ssh.h"
#include "ssh1.h"
#include "key.h"
#include "buffer.h"
#include "bufaux.h"
#include "log.h"

static int argno = 1;		/* Number of argument currently being parsed */

int family = AF_UNSPEC;		/* IPv4, IPv6 or both */

#define MAXMAXFD 256

/* The number of seconds after which to give up on a TCP connection */
int timeout = 5;

int maxfd;
#define maxcon (maxfd - 10)

#ifdef HAVE___PROGNAME
extern char *__progname;
#else
char *__progname;
#endif
fd_set read_wait;
int ncon;

/*
 * Keep a connection structure for each file descriptor.  The state
 * associated with file descriptor n is held in fdcon[n].
 */
typedef struct Connection {
	u_char c_status;	/* State of connection on this file desc. */
#define CS_UNUSED 0		/* File descriptor unused */
#define CS_CON 1		/* Waiting to connect/read greeting */
#define CS_SIZE 2		/* Waiting to read initial packet size */
#define CS_KEYS 3		/* Waiting to read public key packet */
	int c_fd;		/* Quick lookup: c->c_fd == c - fdcon */
	int c_plen;		/* Packet length field for ssh packet */
	int c_len;		/* Total bytes which must be read. */
	int c_off;		/* Length of data read so far. */
	char *c_namebase;	/* Address to free for c_name and c_namelist */
	char *c_name;		/* Hostname of connection for errors */
	char *c_namelist;	/* Pointer to other possible addresses */
	char *c_output_name;	/* Hostname of connection for output */
	char *c_data;		/* Data read from this fd */
	struct timeval c_tv;	/* Time at which connection gets aborted */
	TAILQ_ENTRY(Connection) c_link;	/* List of connections in timeout order. */
} con;

TAILQ_HEAD(conlist, Connection) tq;	/* Timeout Queue */
con *fdcon;

/*
 *  This is just a wrapper around fgets() to make it usable.
 */

/* Stress-test.  Increase this later. */
#define LINEBUF_SIZE 16

typedef struct {
	char *buf;
	u_int size;
	int lineno;
	const char *filename;
	FILE *stream;
	void (*errfun) (const char *,...);
} Linebuf;

static inline Linebuf *
Linebuf_alloc(const char *filename, void (*errfun) (const char *,...))
{
	Linebuf *lb;

	if (!(lb = malloc(sizeof(*lb)))) {
		if (errfun)
			(*errfun) ("linebuf (%s): malloc failed\n", lb->filename);
		return (NULL);
	}
	if (filename) {
		lb->filename = filename;
		if (!(lb->stream = fopen(filename, "r"))) {
			xfree(lb);
			if (errfun)
				(*errfun) ("%s: %s\n", filename, strerror(errno));
			return (NULL);
		}
	} else {
		lb->filename = "(stdin)";
		lb->stream = stdin;
	}

	if (!(lb->buf = malloc(lb->size = LINEBUF_SIZE))) {
		if (errfun)
			(*errfun) ("linebuf (%s): malloc failed\n", lb->filename);
		xfree(lb);
		return (NULL);
	}
	lb->errfun = errfun;
	lb->lineno = 0;
	return (lb);
}

static inline void
Linebuf_free(Linebuf * lb)
{
	fclose(lb->stream);
	xfree(lb->buf);
	xfree(lb);
}

static inline void
Linebuf_restart(Linebuf * lb)
{
	clearerr(lb->stream);
	rewind(lb->stream);
	lb->lineno = 0;
}

static inline int
Linebuf_lineno(Linebuf * lb)
{
	return (lb->lineno);
}

static inline char *
getline(Linebuf * lb)
{
	int n = 0;

	lb->lineno++;
	for (;;) {
		/* Read a line */
		if (!fgets(&lb->buf[n], lb->size - n, lb->stream)) {
			if (ferror(lb->stream) && lb->errfun)
				(*lb->errfun) ("%s: %s\n", lb->filename, strerror(errno));
			return (NULL);
		}
		n = strlen(lb->buf);

		/* Return it or an error if it fits */
		if (n > 0 && lb->buf[n - 1] == '\n') {
			lb->buf[n - 1] = '\0';
			return (lb->buf);
		}
		if (n != lb->size - 1) {
			if (lb->errfun)
				(*lb->errfun) ("%s: skipping incomplete last line\n", lb->filename);
			return (NULL);
		}
		/* Double the buffer if we need more space */
		if (!(lb->buf = realloc(lb->buf, (lb->size *= 2)))) {
			if (lb->errfun)
				(*lb->errfun) ("linebuf (%s): realloc failed\n", lb->filename);
			return (NULL);
		}
	}
}

static int
fdlim_get(int hard)
{
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
	struct rlimit rlfd;
	if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)
		return (-1);
	if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY)
		return 10000;
	else
		return hard ? rlfd.rlim_max : rlfd.rlim_cur;
#elif defined (HAVE_SYSCONF)
	return sysconf (_SC_OPEN_MAX);
#else
	return 10000;
#endif
}

static int
fdlim_set(int lim)
{
#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
	struct rlimit rlfd;
#endif
	if (lim <= 0)
		return (-1);
#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
	if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)
		return (-1);
	rlfd.rlim_cur = lim;
	if (setrlimit(RLIMIT_NOFILE, &rlfd) < 0)
		return (-1);
#elif defined (HAVE_SETDTABLESIZE)
	setdtablesize(lim);
#endif
	return (0);
}

/*
 * This is an strsep function that returns a null field for adjacent
 * separators.  This is the same as the 4.4BSD strsep, but different from the
 * one in the GNU libc.
 */
inline char *
xstrsep(char **str, const char *delim)
{
	char *s, *e;

	if (!**str)
		return (NULL);

	s = *str;
	e = s + strcspn(s, delim);

	if (*e != '\0')
		*e++ = '\0';
	*str = e;

	return (s);
}

/*
 * Get the next non-null token (like GNU strsep).  Strsep() will return a
 * null token for two adjacent separators, so we may have to loop.
 */
char *
strnnsep(char **stringp, char *delim)
{
	char *tok;

	do {
		tok = xstrsep(stringp, delim);
	} while (tok && *tok == '\0');
	return (tok);
}

void
keyprint(char *host, char *output_name, char *kd, int len)
{
	static Key *rsa;
	static Buffer msg;

	if (rsa == NULL) {
		buffer_init(&msg);
		rsa = key_new(KEY_RSA1);
	}
	buffer_append(&msg, kd, len);
	buffer_consume(&msg, 8 - (len & 7));	/* padding */
	if (buffer_get_char(&msg) != (int) SSH_SMSG_PUBLIC_KEY) {
		error("%s: invalid packet type", host);
		buffer_clear(&msg);
		return;
	}
	buffer_consume(&msg, 8);		/* cookie */

	/* server key */
	(void) buffer_get_int(&msg);
	buffer_get_bignum(&msg, rsa->rsa->e);
	buffer_get_bignum(&msg, rsa->rsa->n);

	/* host key */
	(void) buffer_get_int(&msg);
	buffer_get_bignum(&msg, rsa->rsa->e);
	buffer_get_bignum(&msg, rsa->rsa->n);
	buffer_clear(&msg);

	fprintf(stdout, "%s ", output_name ? output_name : host);
	key_write(rsa, stdout);
	fputs("\n", stdout);
}

int
tcpconnect(char *host)
{
	struct addrinfo hints, *ai, *aitop;
	char strport[NI_MAXSERV];
	int gaierr, s = -1;

	snprintf(strport, sizeof strport, "%d", SSH_DEFAULT_PORT);
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;
	if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
		fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr));
	for (ai = aitop; ai; ai = ai->ai_next) {
		s = socket(ai->ai_family, SOCK_STREAM, 0);
		if (s < 0) {
			error("socket: %s", strerror(errno));
			continue;
		}
		if (fcntl(s, F_SETFL, O_NONBLOCK) < 0)
			fatal("F_SETFL: %s", strerror(errno));
		if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0 &&
		    errno != EINPROGRESS)
			error("connect (`%s'): %s", host, strerror(errno));
		else
			break;
		close(s);
		s = -1;
	}
	freeaddrinfo(aitop);
	return s;
}

int
conalloc(char *iname, char *oname)
{
	int s;
	char *namebase, *name, *namelist;

	namebase = namelist = xstrdup(iname);

	do {
		name = xstrsep(&namelist, ",");
		if (!name) {
			xfree(namebase);
			return (-1);
		}
	} while ((s = tcpconnect(name)) < 0);

	if (s >= maxfd)
		fatal("conalloc: fdno %d too high", s);
	if (fdcon[s].c_status)
		fatal("conalloc: attempt to reuse fdno %d", s);

	fdcon[s].c_fd = s;
	fdcon[s].c_status = CS_CON;
	fdcon[s].c_namebase = namebase;
	fdcon[s].c_name = name;
	fdcon[s].c_namelist = namelist;
	fdcon[s].c_output_name = xstrdup(oname);
	fdcon[s].c_data = (char *) &fdcon[s].c_plen;
	fdcon[s].c_len = 4;
	fdcon[s].c_off = 0;
	gettimeofday(&fdcon[s].c_tv, NULL);
	fdcon[s].c_tv.tv_sec += timeout;
	TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
	FD_SET(s, &read_wait);
	ncon++;
	return (s);
}

void
confree(int s)
{
	close(s);
	if (s >= maxfd || fdcon[s].c_status == CS_UNUSED)
		fatal("confree: attempt to free bad fdno %d", s);
	xfree(fdcon[s].c_namebase);
	xfree(fdcon[s].c_output_name);
	if (fdcon[s].c_status == CS_KEYS)
		xfree(fdcon[s].c_data);
	fdcon[s].c_status = CS_UNUSED;
	TAILQ_REMOVE(&tq, &fdcon[s], c_link);
	FD_CLR(s, &read_wait);
	ncon--;
}

void
contouch(int s)
{
	TAILQ_REMOVE(&tq, &fdcon[s], c_link);
	gettimeofday(&fdcon[s].c_tv, NULL);
	fdcon[s].c_tv.tv_sec += timeout;
	TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
}

int
conrecycle(int s)
{
	int ret;
	con *c = &fdcon[s];
	char *iname, *oname;

	iname = xstrdup(c->c_namelist);
	oname = xstrdup(c->c_output_name);
	confree(s);
	ret = conalloc(iname, oname);
	xfree(iname);
	xfree(oname);
	return (ret);
}

void
congreet(int s)
{
	char buf[80];
	int n;
	con *c = &fdcon[s];

	n = read(s, buf, sizeof(buf));
	if (n < 0) {
		if (errno != ECONNREFUSED)
			error("read (%s): %s", c->c_name, strerror(errno));
		conrecycle(s);
		return;
	}
	if (buf[n - 1] != '\n') {
		error("%s: bad greeting", c->c_name);
		confree(s);
		return;
	}
	buf[n - 1] = '\0';
	fprintf(stderr, "# %s %s\n", c->c_name, buf);
	n = snprintf(buf, sizeof buf, "SSH-1.5-OpenSSH-keyscan\r\n");
	if (write(s, buf, n) != n) {
		error("write (%s): %s", c->c_name, strerror(errno));
		confree(s);
		return;
	}
	c->c_status = CS_SIZE;
	contouch(s);
}

void
conread(int s)
{
	int n;
	con *c = &fdcon[s];

	if (c->c_status == CS_CON) {
		congreet(s);
		return;
	}
	n = read(s, c->c_data + c->c_off, c->c_len - c->c_off);
	if (n < 0) {
		error("read (%s): %s", c->c_name, strerror(errno));
		confree(s);
		return;
	}
	c->c_off += n;

	if (c->c_off == c->c_len)
		switch (c->c_status) {
		case CS_SIZE:
			c->c_plen = htonl(c->c_plen);
			c->c_len = c->c_plen + 8 - (c->c_plen & 7);
			c->c_off = 0;
			c->c_data = xmalloc(c->c_len);
			c->c_status = CS_KEYS;
			break;
		case CS_KEYS:
			keyprint(c->c_name, c->c_output_name, c->c_data, c->c_plen);
			confree(s);
			return;
			break;
		default:
			fatal("conread: invalid status %d", c->c_status);
			break;
		}

	contouch(s);
}

void
conloop(void)
{
	fd_set r, e;
	struct timeval seltime, now;
	int i;
	con *c;

	gettimeofday(&now, NULL);
	c = tq.tqh_first;

	if (c &&
	    (c->c_tv.tv_sec > now.tv_sec ||
	     (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec > now.tv_usec))) {
		seltime = c->c_tv;
		seltime.tv_sec -= now.tv_sec;
		seltime.tv_usec -= now.tv_usec;
		if ((int) seltime.tv_usec < 0) {
			seltime.tv_usec += 1000000;
			seltime.tv_sec--;
		}
	} else
		seltime.tv_sec = seltime.tv_usec = 0;

	r = e = read_wait;
	select(maxfd, &r, NULL, &e, &seltime);
	for (i = 0; i < maxfd; i++)
		if (FD_ISSET(i, &e)) {
			error("%s: exception!", fdcon[i].c_name);
			confree(i);
		} else if (FD_ISSET(i, &r))
			conread(i);

	c = tq.tqh_first;
	while (c &&
	       (c->c_tv.tv_sec < now.tv_sec ||
		(c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec < now.tv_usec))) {
		int s = c->c_fd;
		c = c->c_link.tqe_next;
		conrecycle(s);
	}
}

char *
nexthost(int argc, char **argv)
{
	static Linebuf *lb;

	for (;;) {
		if (!lb) {
			if (argno >= argc)
				return (NULL);
			if (argv[argno][0] != '-')
				return (argv[argno++]);
			if (!strcmp(argv[argno], "--")) {
				if (++argno >= argc)
					return (NULL);
				return (argv[argno++]);
			} else if (!strncmp(argv[argno], "-f", 2)) {
				char *fname;
				if (argv[argno][2])
					fname = &argv[argno++][2];
				else if (++argno >= argc) {
					error("missing filename for `-f'");
					return (NULL);
				} else
					fname = argv[argno++];
				if (!strcmp(fname, "-"))
					fname = NULL;
				lb = Linebuf_alloc(fname, error);
			} else
				error("ignoring invalid/misplaced option `%s'", argv[argno++]);
		} else {
			char *line;
			line = getline(lb);
			if (line)
				return (line);
			Linebuf_free(lb);
			lb = NULL;
		}
	}
}

static void
usage(void)
{
	fatal("usage: %s [-t timeout] { [--] host | -f file } ...", __progname);
	return;
}

int
main(int argc, char **argv)
{
	char *host = NULL;

	__progname = get_progname(argv[0]);
	TAILQ_INIT(&tq);

	if (argc <= argno)
		usage();

	if (argv[1][0] == '-' && argv[1][1] == 't') {
		argno++;
		if (argv[1][2])
			timeout = atoi(&argv[1][2]);
		else {
			if (argno >= argc)
				usage();
			timeout = atoi(argv[argno++]);
		}
		if (timeout <= 0)
			usage();
	}
	if (argc <= argno)
		usage();

	maxfd = fdlim_get(1);
	if (maxfd < 0)
		fatal("%s: fdlim_get: bad value", __progname);
	if (maxfd > MAXMAXFD)
		maxfd = MAXMAXFD;
	if (maxcon <= 0)
		fatal("%s: not enough file descriptors", __progname);
	if (maxfd > fdlim_get(0))
		fdlim_set(maxfd);
	fdcon = xmalloc(maxfd * sizeof(con));

	do {
		while (ncon < maxcon) {
			char *name;

			host = nexthost(argc, argv);
			if (host == NULL)
				break;
			name = strnnsep(&host, " \t\n");
			conalloc(name, *host ? host : name);
		}
		conloop();
	} while (host);
	while (ncon > 0)
		conloop();

	return (0);
}
