/* telnetd.c - Telnet Server 
 *
 * Copyright 2013 Sandeep Sharma <sandeep.jack2756@gmail.com>
 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
 *
USE_TELNETD(NEWTOY(telnetd, "w#<0b:p#<0>65535=23f:l:FSKi[!wi]", TOYFLAG_USR|TOYFLAG_BIN))

config TELNETD
  bool "telnetd"
  default n
  help
    Handle incoming telnet connections

    -l LOGIN  Exec LOGIN on connect
    -f ISSUE_FILE Display ISSUE_FILE instead of /etc/issue
    -K Close connection as soon as login exits
    -p PORT   Port to listen on
    -b ADDR[:PORT]  Address to bind to
    -F Run in foreground
    -i Inetd mode
    -w SEC    Inetd 'wait' mode, linger time SEC
    -S Log to syslog (implied by -i or without -F and -w)
*/

#define FOR_telnetd
#include "toys.h"
#include <utmp.h>
GLOBALS(
    char *login_path;
    char *issue_path;
    int port;
    char *host_addr;
    long w_sec;

    int gmax_fd;
    int sig;
    pid_t fork_pid;
)


# define IAC         255  /* interpret as command: */
# define DONT        254  /* you are not to use option */
# define DO          253  /* please, you use option */
# define WONT        252  /* I won't use option */
# define WILL        251  /* I will use option */
# define SB          250  /* interpret as subnegotiation */
# define SE          240  /* end sub negotiation */
# define NOP         241  /* No Operation */
# define TELOPT_ECHO   1  /* echo */
# define TELOPT_SGA    3  /* suppress go ahead */
# define TELOPT_TTYPE 24  /* terminal type */
# define TELOPT_NAWS  31  /* window size */

#define BUFSIZE 4*1024
struct term_session {
  int new_fd, pty_fd;
  pid_t child_pid;
  int buff1_avail, buff2_avail;
  int buff1_written, buff2_written;
  int rem;  //unprocessed data from socket
  char buff1[BUFSIZE], buff2[BUFSIZE];
  struct term_session *next;
};

struct term_session *session_list = NULL;

static void get_sockaddr(char *host, void *buf)
{
  in_port_t port_num = htons(TT.port);
  struct addrinfo hints, *result;
  int status, af = AF_UNSPEC;
  char *s;

  // [ipv6]:port or exactly one :
  if (*host == '[') {
    host++;
    s = strchr(host, ']');
    if (s) *s++ = 0;
    else error_exit("bad address '%s'", host-1);
    af = AF_INET6;
  } else {
    s = strrchr(host, ':');
    if (s && strchr(host, ':') == s) {
      *s = 0;
      af = AF_INET;
    } else if (s && strchr(host, ':') != s) {
      af = AF_INET6;
      s = 0;
    }
  }

  if (s++) {
    char *ss;
    unsigned long p = strtoul(s, &ss, 0);
    if (!*s || *ss || p > 65535) error_exit("bad port '%s'", s);
    port_num = htons(p);
  }

  memset(&hints, 0 , sizeof(struct addrinfo));
  hints.ai_family = af;
  hints.ai_socktype = SOCK_STREAM;

  status = getaddrinfo(host, NULL, &hints, &result);
  if (status) error_exit("bad address '%s' : %s", host, gai_strerror(status));

  memcpy(buf, result->ai_addr, result->ai_addrlen);
  freeaddrinfo(result);

  if (af == AF_INET) ((struct sockaddr_in*)buf)->sin_port = port_num;
  else ((struct sockaddr_in6*)buf)->sin6_port = port_num;
}

static void utmp_entry(void)                                                                                                                                 
{               
  struct utmp entry;
  struct utmp *utp_ptr;
  pid_t pid = getpid();

  utmpname(_PATH_UTMP);
  setutent(); //start from start
  while ((utp_ptr = getutent()) != NULL) {
    if (utp_ptr->ut_pid == pid && utp_ptr->ut_type >= INIT_PROCESS) break;
  }             
  if (!utp_ptr) entry.ut_type = DEAD_PROCESS;
  time(&entry.ut_time);  
  setutent();   
  pututline(&entry);     
}

static int listen_socket(void)
{
  int s, af = AF_INET, yes = 1;
  char buf[sizeof(struct sockaddr_storage)];

  memset(buf, 0, sizeof(buf));
  if (toys.optflags & FLAG_b) {
    get_sockaddr(TT.host_addr, buf);
    af = ((struct sockaddr *)buf)->sa_family;
  } else {
    ((struct sockaddr_in*)buf)->sin_port = htons(TT.port);
    ((struct sockaddr_in*)buf)->sin_family = af;
  }
  s = xsocket(af, SOCK_STREAM, 0);
  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) == -1) 
    perror_exit("setsockopt");

  if (bind(s, (struct sockaddr *)buf, ((af == AF_INET)?
          (sizeof(struct sockaddr_in)):(sizeof(struct sockaddr_in6)))) == -1) {
    close(s);
    perror_exit("bind");
  }

  if (listen(s, 1) < 0) perror_exit("listen");
  return s;
}

static void write_issue(char *tty)
{
  int size;
  char ch = 0;
  struct utsname u;
  int fd = open(TT.issue_path, O_RDONLY);

  if (fd < 0) return ;
  uname(&u);
  while ((size = readall(fd, &ch, 1)) > 0) {
    if (ch == '\\' || ch == '%') {
      if (readall(fd, &ch, 1) <= 0) perror_exit("readall!");
      if (ch == 's') fputs(u.sysname, stdout);
      if (ch == 'n'|| ch == 'h') fputs(u.nodename, stdout);
      if (ch == 'r') fputs(u.release, stdout);
      if (ch == 'm') fputs(u.machine, stdout);
      if (ch == 'l') fputs(tty, stdout);
    }
    else if (ch == '\n') {
      fputs("\n\r\0", stdout);
    } else fputc(ch, stdout);
  }
  fflush(NULL);
  close(fd);
}

static int new_session(int sockfd)
{
  char *argv_login[2]; //arguments for execvp cmd, NULL
  char tty_name[30]; //tty name length.
  int fd, flags, i = 1;
  char intial_iacs[] = {IAC, DO, TELOPT_ECHO, IAC, DO, TELOPT_NAWS,
    IAC, WILL, TELOPT_ECHO, IAC, WILL, TELOPT_SGA };

  setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i));
  flags = fcntl(sockfd, F_GETFL);
  fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
  if (toys.optflags & FLAG_i) fcntl((sockfd + 1), F_SETFL, flags | O_NONBLOCK);

  writeall((toys.optflags & FLAG_i)?1:sockfd, intial_iacs, sizeof(intial_iacs));
  if ((TT.fork_pid = forkpty(&fd, tty_name, NULL, NULL)) > 0) {
    flags = fcntl(fd, F_GETFL);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    return fd;
  }
  if (TT.fork_pid < 0) perror_exit("fork");
  write_issue(tty_name);
  argv_login[0] = strdup(TT.login_path);
  argv_login[1] = NULL;
  execvp(argv_login[0], argv_login);
  exit(EXIT_FAILURE);
}

static int handle_iacs(struct term_session *tm, int c, int fd)
{
  char *curr ,*start,*end;
  int i = 0;

  curr = start = tm->buff2+tm->buff2_avail; 
  end = tm->buff2 + c -1;
  tm->rem = 0;
  while (curr <= end) {
    if (*curr != IAC){

      if (*curr != '\r') {
        toybuf[i++] = *curr++;
        continue;
      } else {
        toybuf[i++] = *curr++;
        curr++;
        if (curr < end && (*curr == '\n' || *curr == '\0')) 
          curr++;
        continue;
      }
    }

    if ((curr + 1) > end) {
      tm->rem = 1;
      break; 
    }
    if (*(curr+1) == IAC) { //IAC as data --> IAC IAC
      toybuf[i++] = *(curr+1);
      curr += 2; //IAC IAC --> 2 bytes
      continue;
    }
    if (*(curr + 1) == NOP || *(curr + 1) == SE) {
      curr += 2;
      continue;
    }

    if (*(curr + 1) == SB ) {
      if (*(curr+2) == TELOPT_NAWS) {
        struct winsize ws;
        if ((curr+8) >= end) {  //ensure we have data to process.
          tm->rem = end - curr; 
          break;  
        }
        ws.ws_col = (curr[3] << 8) | curr[4];
        ws.ws_row = (curr[5] << 8) | curr[6];
        ioctl(fd, TIOCSWINSZ, (char *)&ws);
        curr += 9;
        continue;
      } else { //eat non-supported sub neg. options.
        curr++, tm->rem++;
        while (*curr != IAC && curr <= end) {
          curr++;
          tm->rem++;
        } 
        if (*curr == IAC) {
          tm->rem = 0;
          continue;
        } else break;
      }
    }
    curr += 3; //skip non-supported 3 bytes.
  }
  memcpy(start, toybuf, i);
  memcpy(start + i, end - tm->rem, tm->rem); //put remaining if we break;
  return i;
}

static int dup_iacs(char *start, int fd, int len)
{
  char arr[] = {IAC, IAC};
  char *needle = NULL;
  int ret = 0, c, count = 0;

  while (len) {
    if (*start == IAC) {
      count = writeall(fd, arr, sizeof(arr));
      if (count != 2) break; //short write
      start++;
      ret++;
      len--;
      continue;
    }
    needle = memchr(start, IAC, len);
    if (needle) c = needle - start;
    else c = len;
    count = writeall(fd, start, c);
    if (count < 0) break; 
    len -= count;
    ret += count;
    start += count;
  }
  return ret;
}

static void kill_session(void)
{
  int status;
  struct term_session *tm, *prev = NULL;
  pid_t pid = wait(&status);
  TT.sig = 0; //ASAP

  tm = session_list;
  if (toys.optflags & FLAG_i) exit(EXIT_SUCCESS);

  if (pid < 0) return;
  while (tm) {
    if (tm->child_pid == pid) break;
    prev = tm;
    tm = tm->next;
  }
  if (!tm) return; //paranoia
  if (!prev) session_list = session_list->next;
  else prev->next = tm->next;
  utmp_entry();
  xclose(tm->pty_fd);
  xclose(tm->new_fd);
  free(tm);
}

static void session_handler(int sig) 
{
  TT.sig = sig;
}

void telnetd_main(void)
{
  errno = 0;
  fd_set rd, wr;
  struct term_session *tm = NULL;
  struct timeval tv, *tv_ptr = NULL;
  int pty_fd, new_fd, c = 0, w, master_fd = 0;
  int inetd_m = (toys.optflags & FLAG_i);

  TT.sig = 0;
  if (!(toys.optflags & FLAG_l)) TT.login_path = "/bin/login";
  if (!(toys.optflags & FLAG_f)) TT.issue_path = "/etc/issue.net";
  if (toys.optflags & FLAG_w) toys.optflags |= FLAG_F;
  if (!inetd_m) {
    master_fd = listen_socket();
    fcntl(master_fd, F_SETFD, FD_CLOEXEC);
    if (master_fd > TT.gmax_fd) TT.gmax_fd = master_fd;
    if (!(toys.optflags & FLAG_F)) daemonize(); 
  } else {
    pty_fd = new_session(master_fd); //master_fd = 0
    if (pty_fd > TT.gmax_fd) TT.gmax_fd = pty_fd;
    tm = xzalloc(sizeof(struct term_session));
    tm->child_pid = TT.fork_pid;
    tm->new_fd = 0;    
    tm->pty_fd = pty_fd;    
    if (session_list) {     
      tm->next = session_list;
      session_list = tm;    
    } else session_list = tm;
  }

  if ((toys.optflags & FLAG_w) && !session_list) {
    tv.tv_sec = TT.w_sec;
    tv.tv_usec = 0;
    tv_ptr = &tv;
  }                
  signal(SIGCHLD, session_handler);

  for (;;) {
    FD_ZERO(&rd);
    FD_ZERO(&wr);
    if (!inetd_m) FD_SET(master_fd, &rd);

    tm = session_list;
    while (tm) {

      if (tm->pty_fd > 0 && tm->buff1_avail < BUFSIZE) FD_SET(tm->pty_fd, &rd);
      if (tm->new_fd >= 0 && tm->buff2_avail < BUFSIZE) FD_SET(tm->new_fd, &rd);
      if (tm->pty_fd > 0 && (tm->buff2_avail - tm->buff2_written) > 0)  
        FD_SET(tm->pty_fd, &wr);
      if (tm->new_fd >= 0 && (tm->buff1_avail - tm->buff1_written) > 0)  
        FD_SET(tm->new_fd, &wr);
      tm = tm->next;
    }


    int r = select(TT.gmax_fd + 1, &rd, &wr, NULL, tv_ptr);
    if (!r) return; //timeout
    if (r < -1) continue;

    if (!inetd_m && FD_ISSET(master_fd, &rd)) { //accept new connection
      new_fd = accept(master_fd, NULL, NULL);
      if (new_fd < 0) continue;
      tv_ptr = NULL;
      fcntl(new_fd, F_SETFD, FD_CLOEXEC);
      if (new_fd > TT.gmax_fd) TT.gmax_fd = new_fd;
      pty_fd = new_session(new_fd);
      if (pty_fd > TT.gmax_fd) TT.gmax_fd = pty_fd;

      tm = xzalloc(sizeof(struct term_session));
      tm->child_pid = TT.fork_pid;
      tm->new_fd = new_fd;
      tm->pty_fd = pty_fd;
      if (session_list) {
        tm->next = session_list;
        session_list = tm;
      } else session_list = tm;
    }

    tm = session_list;
    for (;tm;tm=tm->next) {
      if (FD_ISSET(tm->pty_fd, &rd)) {
        if ((c = read(tm->pty_fd, tm->buff1 + tm->buff1_avail,
                BUFSIZE-tm->buff1_avail)) <= 0) break;
        tm->buff1_avail += c;
        if ((w = dup_iacs(tm->buff1 + tm->buff1_written, tm->new_fd + inetd_m,
                tm->buff1_avail - tm->buff1_written)) < 0) break;
        tm->buff1_written += w;
      }
      if (FD_ISSET(tm->new_fd, &rd)) {
        if ((c = read(tm->new_fd, tm->buff2+tm->buff2_avail,
                BUFSIZE-tm->buff2_avail)) <= 0) break;
        c = handle_iacs(tm, c, tm->pty_fd);
        tm->buff2_avail += c;
        if ((w = write(tm->pty_fd, tm->buff2+ tm->buff2_written, 
                tm->buff2_avail - tm->buff2_written)) < 0) break;
        tm->buff2_written += w;
      }
      if (FD_ISSET(tm->pty_fd, &wr)) {
        if ((w = write(tm->pty_fd,  tm->buff2 + tm->buff2_written, 
                tm->buff2_avail - tm->buff2_written)) < 0) break;
        tm->buff2_written += w;
      }
      if (FD_ISSET(tm->new_fd, &wr)) {
        if ((w = dup_iacs(tm->buff1 + tm->buff1_written, tm->new_fd + inetd_m,
                tm->buff1_avail - tm->buff1_written)) < 0) break;
        tm->buff1_written += w;
      }
      if (tm->buff1_written == tm->buff1_avail)
        tm->buff1_written = tm->buff1_avail = 0;
      if (tm->buff2_written == tm->buff2_avail)
        tm->buff2_written = tm->buff2_avail = 0;
      fflush(NULL);
    }
    if (TT.sig) kill_session();
  }
}
