/* vi: set sw=4 ts=4: */
/*
 * Simple telnet server
 * Bjorn Wesen, Axis Communications AB (bjornw@axis.com)
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 *
 * ---------------------------------------------------------------------------
 * (C) Copyright 2000, Axis Communications AB, LUND, SWEDEN
 ****************************************************************************
 *
 * The telnetd manpage says it all:
 *
 *   Telnetd operates by allocating a pseudo-terminal device (see pty(4))  for
 *   a client, then creating a login process which has the slave side of the
 *   pseudo-terminal as stdin, stdout, and stderr. Telnetd manipulates the
 *   master side of the pseudo-terminal, implementing the telnet protocol and
 *   passing characters between the remote client and the login process.
 *
 * Vladimir Oleynik <dzo@simtreas.ru> 2001
 *     Set process group corrections, initial busybox port
 */

#define DEBUG 0

#include "libbb.h"

#if DEBUG
#define TELCMDS
#define TELOPTS
#endif
#include <arpa/telnet.h>
#include <sys/syslog.h>


#if ENABLE_LOGIN
static const char *loginpath = "/bin/login";
#else
static const char *loginpath = DEFAULT_SHELL;
#endif

static const char *issuefile = "/etc/issue.net";

/* structure that describes a session */

struct tsession {
	struct tsession *next;
	int sockfd_read, sockfd_write, ptyfd;
	int shell_pid;
	/* two circular buffers */
	char *buf1, *buf2;
	int rdidx1, wridx1, size1;
	int rdidx2, wridx2, size2;
};

/* Two buffers are directly after tsession in malloced memory.
 * Make whole thing fit in 4k */
enum { BUFSIZE = (4*1024 - sizeof(struct tsession)) / 2 };

/*
   This is how the buffers are used. The arrows indicate the movement
   of data.

   +-------+     wridx1++     +------+     rdidx1++     +----------+
   |       | <--------------  | buf1 | <--------------  |          |
   |       |     size1--      +------+     size1++      |          |
   |  pty  |                                            |  socket  |
   |       |     rdidx2++     +------+     wridx2++     |          |
   |       |  --------------> | buf2 |  --------------> |          |
   +-------+     size2++      +------+     size2--      +----------+

   Each session has got two buffers.
*/

static int maxfd;

static struct tsession *sessions;


/*
   Remove all IAC's from the buffer pointed to by bf (received IACs are ignored
   and must be removed so as to not be interpreted by the terminal).  Make an
   uninterrupted string of characters fit for the terminal.  Do this by packing
   all characters meant for the terminal sequentially towards the end of bf.

   Return a pointer to the beginning of the characters meant for the terminal.
   and make *num_totty the number of characters that should be sent to
   the terminal.

   Note - If an IAC (3 byte quantity) starts before (bf + len) but extends
   past (bf + len) then that IAC will be left unprocessed and *processed will be
   less than len.

   FIXME - if we mean to send 0xFF to the terminal then it will be escaped,
   what is the escape character?  We aren't handling that situation here.

   CR-LF ->'s CR mapping is also done here, for convenience
 */
static char *
remove_iacs(struct tsession *ts, int *pnum_totty)
{
	unsigned char *ptr0 = (unsigned char *)ts->buf1 + ts->wridx1;
	unsigned char *ptr = ptr0;
	unsigned char *totty = ptr;
	unsigned char *end = ptr + MIN(BUFSIZE - ts->wridx1, ts->size1);
	int processed;
	int num_totty;

	while (ptr < end) {
		if (*ptr != IAC) {
			int c = *ptr;
			*totty++ = *ptr++;
			/* We now map \r\n ==> \r for pragmatic reasons.
			 * Many client implementations send \r\n when
			 * the user hits the CarriageReturn key.
			 */
			if (c == '\r' && (*ptr == '\n' || *ptr == 0) && ptr < end)
				ptr++;
		} else {
			/*
			 * TELOPT_NAWS support!
			 */
			if ((ptr+2) >= end) {
				/* only the beginning of the IAC is in the
				buffer we were asked to process, we can't
				process this char. */
				break;
			}

			/*
			 * IAC -> SB -> TELOPT_NAWS -> 4-byte -> IAC -> SE
			 */
			else if (ptr[1] == SB && ptr[2] == TELOPT_NAWS) {
				struct winsize ws;
				if ((ptr+8) >= end)
					break;	/* incomplete, can't process */
				ws.ws_col = (ptr[3] << 8) | ptr[4];
				ws.ws_row = (ptr[5] << 8) | ptr[6];
				ioctl(ts->ptyfd, TIOCSWINSZ, (char *)&ws);
				ptr += 9;
			} else {
				/* skip 3-byte IAC non-SB cmd */
#if DEBUG
				fprintf(stderr, "Ignoring IAC %s,%s\n",
					TELCMD(ptr[1]), TELOPT(ptr[2]));
#endif
				ptr += 3;
			}
		}
	}

	processed = ptr - ptr0;
	num_totty = totty - ptr0;
	/* the difference between processed and num_to tty
	   is all the iacs we removed from the stream.
	   Adjust buf1 accordingly. */
	ts->wridx1 += processed - num_totty;
	ts->size1 -= processed - num_totty;
	*pnum_totty = num_totty;
	/* move the chars meant for the terminal towards the end of the
	buffer. */
	return memmove(ptr - num_totty, ptr0, num_totty);
}


static int
getpty(char *line, int size)
{
	int p;
#if ENABLE_FEATURE_DEVPTS
	p = open("/dev/ptmx", O_RDWR);
	if (p > 0) {
		const char *name;
		grantpt(p);
		unlockpt(p);
		name = ptsname(p);
		if (!name) {
			bb_perror_msg("ptsname error (is /dev/pts mounted?)");
			return -1;
		}
		safe_strncpy(line, name, size);
		return p;
	}
#else
	struct stat stb;
	int i;
	int j;

	strcpy(line, "/dev/ptyXX");

	for (i = 0; i < 16; i++) {
		line[8] = "pqrstuvwxyzabcde"[i];
		line[9] = '0';
		if (stat(line, &stb) < 0) {
			continue;
		}
		for (j = 0; j < 16; j++) {
			line[9] = j < 10 ? j + '0' : j - 10 + 'a';
			if (DEBUG)
				fprintf(stderr, "Trying to open device: %s\n", line);
			p = open(line, O_RDWR | O_NOCTTY);
			if (p >= 0) {
				line[5] = 't';
				return p;
			}
		}
	}
#endif /* FEATURE_DEVPTS */
	return -1;
}


static void
send_iac(struct tsession *ts, unsigned char command, int option)
{
	/* We rely on that there is space in the buffer for now. */
	char *b = ts->buf2 + ts->rdidx2;
	*b++ = IAC;
	*b++ = command;
	*b++ = option;
	ts->rdidx2 += 3;
	ts->size2 += 3;
}


static struct tsession *
make_new_session(
		USE_FEATURE_TELNETD_STANDALONE(int sock_r, int sock_w)
		SKIP_FEATURE_TELNETD_STANDALONE(void)
) {
	const char *login_argv[2];
	struct termios termbuf;
	int fd, pid;
	char tty_name[32];
	struct tsession *ts = xzalloc(sizeof(struct tsession) + BUFSIZE * 2);

	ts->buf1 = (char *)(&ts[1]);
	ts->buf2 = ts->buf1 + BUFSIZE;

	/* Got a new connection, set up a tty. */
	fd = getpty(tty_name, 32);
	if (fd < 0) {
		bb_error_msg("all terminals in use");
		return NULL;
	}
	if (fd > maxfd) maxfd = fd;
	ndelay_on(ts->ptyfd = fd);
#if ENABLE_FEATURE_TELNETD_STANDALONE
	if (sock_w > maxfd) maxfd = sock_w;
	if (sock_r > maxfd) maxfd = sock_r;
	ndelay_on(ts->sockfd_write = sock_w);
	ndelay_on(ts->sockfd_read = sock_r);
#else
	ts->sockfd_write = 1;
	/* xzalloc: ts->sockfd_read = 0; */
	ndelay_on(0);
	ndelay_on(1);
#endif
	/* Make the telnet client understand we will echo characters so it
	 * should not do it locally. We don't tell the client to run linemode,
	 * because we want to handle line editing and tab completion and other
	 * stuff that requires char-by-char support. */
	send_iac(ts, DO, TELOPT_ECHO);
	send_iac(ts, DO, TELOPT_NAWS);
	send_iac(ts, DO, TELOPT_LFLOW);
	send_iac(ts, WILL, TELOPT_ECHO);
	send_iac(ts, WILL, TELOPT_SGA);

	pid = fork();
	if (pid < 0) {
		free(ts);
		close(fd);
		bb_perror_msg("fork");
		return NULL;
	}
	if (pid > 0) {
		/* parent */
		ts->shell_pid = pid;
		return ts;
	}

	/* child */

	/* make new session and process group */
	setsid();

	/* open the child's side of the tty. */
	/* NB: setsid() disconnects from any previous ctty's. Therefore
	 * we must open child's side of the tty AFTER setsid! */
	fd = xopen(tty_name, O_RDWR); /* becomes our ctty */
	dup2(fd, 0);
	dup2(fd, 1);
	dup2(fd, 2);
	while (fd > 2) close(fd--);
	tcsetpgrp(0, getpid()); /* switch this tty's process group to us */

	/* The pseudo-terminal allocated to the client is configured to operate in
	 * cooked mode, and with XTABS CRMOD enabled (see tty(4)). */
	tcgetattr(0, &termbuf);
	termbuf.c_lflag |= ECHO; /* if we use readline we dont want this */
	termbuf.c_oflag |= ONLCR|XTABS;
	termbuf.c_iflag |= ICRNL;
	termbuf.c_iflag &= ~IXOFF;
	/*termbuf.c_lflag &= ~ICANON;*/
	tcsetattr(0, TCSANOW, &termbuf);

	print_login_issue(issuefile, NULL);

	/* exec shell / login /whatever */
	login_argv[0] = loginpath;
	login_argv[1] = NULL;
	execv(loginpath, (char **)login_argv);
	/* Hmmm... this gets sent to the client thru fd#2! Is it ok?? */
	bb_perror_msg_and_die("execv %s", loginpath);
}

#if ENABLE_FEATURE_TELNETD_STANDALONE

static void
free_session(struct tsession *ts)
{
	struct tsession *t = sessions;

	/* unlink this telnet session from the session list */
	if (t == ts)
		sessions = ts->next;
	else {
		while (t->next != ts)
			t = t->next;
		t->next = ts->next;
	}

	kill(ts->shell_pid, SIGKILL);
	wait4(ts->shell_pid, NULL, 0, NULL);
	close(ts->ptyfd);
	close(ts->sockfd_read);
	/* error if ts->sockfd_read == ts->sockfd_write. So what? ;) */
	close(ts->sockfd_write);
	free(ts);

	/* scan all sessions and find new maxfd */
	ts = sessions;
	maxfd = 0;
	while (ts) {
		if (maxfd < ts->ptyfd)
			maxfd = ts->ptyfd;
		if (maxfd < ts->sockfd_read)
			maxfd = ts->sockfd_read;
		if (maxfd < ts->sockfd_write)
			maxfd = ts->sockfd_write;
		ts = ts->next;
	}
}

#else /* !FEATURE_TELNETD_STANDALONE */

/* Never actually called */
void free_session(struct tsession *ts);

#endif


int telnetd_main(int argc, char **argv);
int telnetd_main(int argc, char **argv)
{
	fd_set rdfdset, wrfdset;
	unsigned opt;
	int selret, maxlen, w, r;
	struct tsession *ts;
#if ENABLE_FEATURE_TELNETD_STANDALONE
#define IS_INETD (opt & OPT_INETD)
	int master_fd = -1; /* be happy, gcc */
	unsigned portnbr = 23;
	char *opt_bindaddr = NULL;
	char *opt_portnbr;
#else
	enum {
		IS_INETD = 1,
		master_fd = -1,
		portnbr = 23,
	};
#endif
	enum {
		OPT_PORT = 4 * ENABLE_FEATURE_TELNETD_STANDALONE,
		OPT_FOREGROUND = 0x10 * ENABLE_FEATURE_TELNETD_STANDALONE,
		OPT_INETD = 0x20 * ENABLE_FEATURE_TELNETD_STANDALONE,
	};

	opt = getopt32(argv, "f:l:" USE_FEATURE_TELNETD_STANDALONE("p:b:Fi"),
			&issuefile, &loginpath
			USE_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr));
	/* Redirect log to syslog early, if needed */
	if (IS_INETD || !(opt & OPT_FOREGROUND)) {
		openlog(applet_name, 0, LOG_USER);
		logmode = LOGMODE_SYSLOG;
	}
	//if (opt & 1) // -f
	//if (opt & 2) // -l
	USE_FEATURE_TELNETD_STANDALONE(
		if (opt & OPT_PORT) // -p
			portnbr = xatou16(opt_portnbr);
		//if (opt & 8) // -b
		//if (opt & 0x10) // -F
		//if (opt & 0x20) // -i
	);

	/* Used to check access(loginpath, X_OK) here. Pointless.
	 * exec will do this for us for free later. */

#if ENABLE_FEATURE_TELNETD_STANDALONE
	if (IS_INETD) {
		sessions = make_new_session(0, 1);
	} else {
		master_fd = create_and_bind_stream_or_die(opt_bindaddr, portnbr);
		xlisten(master_fd, 1);
		if (!(opt & OPT_FOREGROUND))
			bb_daemonize(DAEMON_CHDIR_ROOT);
	}
#else
	sessions = make_new_session();
#endif

	/* We don't want to die if just one session is broken */
	signal(SIGPIPE, SIG_IGN);

 again:
	FD_ZERO(&rdfdset);
	FD_ZERO(&wrfdset);
	if (!IS_INETD) {
		FD_SET(master_fd, &rdfdset);
		/* This is needed because free_session() does not
		 * take into account master_fd when it finds new
		 * maxfd among remaining fd's: */
		if (master_fd > maxfd)
			maxfd = master_fd;
	}

	/* select on the master socket, all telnet sockets and their
	 * ptys if there is room in their session buffers. */
	ts = sessions;
	while (ts) {
		/* buf1 is used from socket to pty
		 * buf2 is used from pty to socket */
		if (ts->size1 > 0)       /* can write to pty */
			FD_SET(ts->ptyfd, &wrfdset);
		if (ts->size1 < BUFSIZE) /* can read from socket */
			FD_SET(ts->sockfd_read, &rdfdset);
		if (ts->size2 > 0)       /* can write to socket */
			FD_SET(ts->sockfd_write, &wrfdset);
		if (ts->size2 < BUFSIZE) /* can read from pty */
			FD_SET(ts->ptyfd, &rdfdset);
		ts = ts->next;
	}

	selret = select(maxfd + 1, &rdfdset, &wrfdset, 0, 0);
	if (!selret)
		return 0;

#if ENABLE_FEATURE_TELNETD_STANDALONE
	/* First check for and accept new sessions. */
	if (!IS_INETD && FD_ISSET(master_fd, &rdfdset)) {
		int fd;
		struct tsession *new_ts;

		fd = accept(master_fd, NULL, 0);
		if (fd < 0)
			goto again;
		/* Create a new session and link it into our active list */
		new_ts = make_new_session(fd, fd);
		if (new_ts) {
			new_ts->next = sessions;
			sessions = new_ts;
		} else {
			close(fd);
		}
	}
#endif

	/* Then check for data tunneling. */
	ts = sessions;
	while (ts) { /* For all sessions... */
		struct tsession *next = ts->next; /* in case we free ts. */

		if (ts->size1 && FD_ISSET(ts->ptyfd, &wrfdset)) {
			int num_totty;
			char *ptr;
			/* Write to pty from buffer 1. */
			ptr = remove_iacs(ts, &num_totty);
			w = safe_write(ts->ptyfd, ptr, num_totty);
			/* needed? if (w < 0 && errno == EAGAIN) continue; */
			if (w < 0) {
				if (IS_INETD)
					return 0;
				free_session(ts);
				ts = next;
				continue;
			}
			ts->wridx1 += w;
			ts->size1 -= w;
			if (ts->wridx1 == BUFSIZE)
				ts->wridx1 = 0;
		}

		if (ts->size2 && FD_ISSET(ts->sockfd_write, &wrfdset)) {
			/* Write to socket from buffer 2. */
			maxlen = MIN(BUFSIZE - ts->wridx2, ts->size2);
			w = safe_write(ts->sockfd_write, ts->buf2 + ts->wridx2, maxlen);
			/* needed? if (w < 0 && errno == EAGAIN) continue; */
			if (w < 0) {
				if (IS_INETD)
					return 0;
				free_session(ts);
				ts = next;
				continue;
			}
			ts->wridx2 += w;
			ts->size2 -= w;
			if (ts->wridx2 == BUFSIZE)
				ts->wridx2 = 0;
		}

		if (ts->size1 < BUFSIZE && FD_ISSET(ts->sockfd_read, &rdfdset)) {
			/* Read from socket to buffer 1. */
			maxlen = MIN(BUFSIZE - ts->rdidx1, BUFSIZE - ts->size1);
			r = safe_read(ts->sockfd_read, ts->buf1 + ts->rdidx1, maxlen);
			if (r < 0 && errno == EAGAIN) continue;
			if (r <= 0) {
				if (IS_INETD)
					return 0;
				free_session(ts);
				ts = next;
				continue;
			}
			if (!ts->buf1[ts->rdidx1 + r - 1])
				if (!--r)
					continue;
			ts->rdidx1 += r;
			ts->size1 += r;
			if (ts->rdidx1 == BUFSIZE)
				ts->rdidx1 = 0;
		}

		if (ts->size2 < BUFSIZE && FD_ISSET(ts->ptyfd, &rdfdset)) {
			/* Read from pty to buffer 2. */
			maxlen = MIN(BUFSIZE - ts->rdidx2, BUFSIZE - ts->size2);
			r = safe_read(ts->ptyfd, ts->buf2 + ts->rdidx2, maxlen);
			if (r < 0 && errno == EAGAIN) continue;
			if (r <= 0) {
				if (IS_INETD)
					return 0;
				free_session(ts);
				ts = next;
				continue;
			}
			ts->rdidx2 += r;
			ts->size2 += r;
			if (ts->rdidx2 == BUFSIZE)
				ts->rdidx2 = 0;
		}

		if (ts->size1 == 0) {
			ts->rdidx1 = 0;
			ts->wridx1 = 0;
		}
		if (ts->size2 == 0) {
			ts->rdidx2 = 0;
			ts->wridx2 = 0;
		}
		ts = next;
	}
	goto again;
}
