/*
 * 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.15 2001/02/09 09:04:59 itojun 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 *
Linebuf_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 (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 = Linebuf_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));
	memset(fdcon, 0, 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);
}
