/* $OpenBSD: sshpty.c,v 1.31 2016/11/29 03:54:50 dtucker Exp $ */
/*
 * Author: Tatu Ylonen <ylo@cs.hut.fi>
 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 *                    All rights reserved
 * Allocating a pseudo-terminal, and making it the controlling tty.
 *
 * As far as I am concerned, the code I have written for this software
 * can be used freely for any purpose.  Any derived versions of this
 * software must be clearly marked as such, and if the derived work is
 * incompatible with the protocol description in the RFC file, it must be
 * called by a name other than "ssh" or "Secure Shell".
 */

#include "includes.h"

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <signal.h>

#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#include <pwd.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#ifdef HAVE_UTIL_H
# include <util.h>
#endif
#include <unistd.h>

#include "sshpty.h"
#include "log.h"
#include "misc.h"

#ifdef HAVE_PTY_H
#ifndef __Fuchsia__
# include <pty.h>
#endif // __Fuchsia__
#endif

#ifndef O_NOCTTY
#define O_NOCTTY 0
#endif

#ifdef __APPLE__
# include <AvailabilityMacros.h>
# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
#  define __APPLE_PRIVPTY__
# endif
#endif

#ifdef __Fuchsia__
#include <fuchsia/hardware/pty/c/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/unsafe.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#endif  // __Fuchsia__

#ifdef __Fuchsia__
static int fuchsia_get_new_pty_server(void) {
  zx_handle_t local, remote;
  zx_status_t status = zx_channel_create(0, &local, &remote);
  int fd = -1;
  if (status != ZX_OK) {
    error("channel create failed: %s", zx_status_get_string(status));
    goto bail;
  }
  status = fdio_service_connect("/svc/fuchsia.hardware.pty.Device", remote);
  remote = ZX_HANDLE_INVALID;
  if (status != ZX_OK) {
    error("fdio_service_connect failed: %s", zx_status_get_string(status));
    goto bail;
  }

  status = fdio_fd_create(local, &fd);
  local = ZX_HANDLE_INVALID;
  if (status != ZX_OK) {
    error("fdio_service_connect failed: %s", zx_status_get_string(status));
    goto bail;
  }
  int flags = fcntl(fd, F_GETFL);
  if (flags < 0) {
    error("fcntl(F_GETFL): %s", strerror(errno));
    goto bail;
  }
  if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
    error("fcntl(F_SETFL): %s", strerror(errno));
    goto bail;
  }
  return fd;

bail:
  zx_handle_close(local);
  zx_handle_close(remote);
  close(fd);
  return -1;
}
#endif  // __Fuchsia__

/*
 * Allocates and opens a pty.  Returns 0 if no pty could be allocated, or
 * nonzero if a pty was successfully allocated.  On success, open file
 * descriptors for the pty and tty sides and the name of the tty side are
 * returned (the buffer must be able to hold at least 64 characters).
 */

int
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
{
#ifdef __Fuchsia__
  *ptyfd = fuchsia_get_new_pty_server();
  if (*ptyfd < 0) {
    return 0;
  }
  *ttyfd = fuchsia_open_pty_client(*ptyfd, 0);
  if (*ttyfd < 0) {
    return 0;
  }
  // ssh thinks it wants to be able to manipulate a PTY by filename but
  // that isn't possible on Fuchsia.
  strlcpy(namebuf, "/dev/not-a-file", namebuflen);
#else
  /* openpty(3) exists in OSF/1 and some other os'es */
  char *name;
  int i;

  i = openpty(ptyfd, ttyfd, NULL, NULL, NULL);
  if (i < 0) {
    error("openpty: %.100s", strerror(errno));
    return 0;
  }
  name = ttyname(*ttyfd);
  if (!name)
    fatal("openpty returns device for which ttyname fails.");

  strlcpy(namebuf, name, namebuflen); /* possible truncation */
#endif  // __Fuchsia__
	return 1;
}

/* Releases the tty.  Its ownership is returned to root, and permissions to 0666. */

void
pty_release(const char *tty)
{
#if !defined(__APPLE_PRIVPTY__) && !defined(HAVE_OPENPTY)
	if (chown(tty, (uid_t) 0, (gid_t) 0) < 0)
		error("chown %.100s 0 0 failed: %.100s", tty, strerror(errno));
	if (chmod(tty, (mode_t) 0666) < 0)
		error("chmod %.100s 0666 failed: %.100s", tty, strerror(errno));
#endif /* !__APPLE_PRIVPTY__ && !HAVE_OPENPTY */
}

/* Makes the tty the process's controlling tty and sets it to sane modes. */

void
pty_make_controlling_tty(int *ttyfd, const char *tty)
{
	int fd;

	/* First disconnect from the old controlling tty. */
#ifdef TIOCNOTTY
	fd = open(_PATH_TTY, O_RDWR | O_NOCTTY);
	if (fd >= 0) {
		(void) ioctl(fd, TIOCNOTTY, NULL);
		close(fd);
	}
#endif /* TIOCNOTTY */
	if (setsid() < 0)
		error("setsid: %.100s", strerror(errno));

	/*
	 * Verify that we are successfully disconnected from the controlling
	 * tty.
	 */
	fd = open(_PATH_TTY, O_RDWR | O_NOCTTY);
	if (fd >= 0) {
		error("Failed to disconnect from controlling tty.");
		close(fd);
	}
	/* Make it our controlling tty. */
#ifdef TIOCSCTTY
	debug("Setting controlling tty using TIOCSCTTY.");
	if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0)
		error("ioctl(TIOCSCTTY): %.100s", strerror(errno));
#endif /* TIOCSCTTY */
#ifdef NEED_SETPGRP
	if (setpgrp(0,0) < 0)
		error("SETPGRP %s",strerror(errno));
#endif /* NEED_SETPGRP */
	fd = open(tty, O_RDWR);
	if (fd < 0)
		error("%.100s: %.100s", tty, strerror(errno));
	else
		close(fd);

	/* Verify that we now have a controlling tty. */
	fd = open(_PATH_TTY, O_WRONLY);
	if (fd < 0)
		error("open /dev/tty failed - could not set controlling tty: %.100s",
		    strerror(errno));
	else
		close(fd);
}

/* Changes the window size associated with the pty. */

void
pty_change_window_size(int ptyfd, u_int row, u_int col,
	u_int xpixel, u_int ypixel)
{
#ifdef __Fuchsia__
    fdio_t* io = fdio_unsafe_fd_to_io(ptyfd);
    fuchsia_hardware_pty_WindowSize w;
	zx_status_t status;

	w.width = col;
	w.height = row;

	fuchsia_hardware_pty_DeviceSetWindowSize(fdio_unsafe_borrow_channel(io), &w, &status);
    fdio_unsafe_release(io);
#else
	struct winsize w;

	/* may truncate u_int -> u_short */
	w.ws_row = row;
	w.ws_col = col;
	w.ws_xpixel = xpixel;
	w.ws_ypixel = ypixel;
	(void) ioctl(ptyfd, TIOCSWINSZ, &w);
#endif  // __Fuchsia__
}

void
pty_setowner(struct passwd *pw, const char *tty)
{
#ifdef __Fuchsia__
        // This is meaningless on Fuchsia.
        return;
#endif

	struct group *grp;
	gid_t gid;
	mode_t mode;
	struct stat st;

	/* Determine the group to make the owner of the tty. */
	grp = getgrnam("tty");
	gid = (grp != NULL) ? grp->gr_gid : pw->pw_gid;
	mode = (grp != NULL) ? 0620 : 0600;

	/*
	 * Change owner and mode of the tty as required.
	 * Warn but continue if filesystem is read-only and the uids match/
	 * tty is owned by root.
	 */
	if (stat(tty, &st))
		fatal("stat(%.100s) failed: %.100s", tty,
		    strerror(errno));

#ifdef WITH_SELINUX
	ssh_selinux_setup_pty(pw->pw_name, tty);
#endif

	if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
		if (chown(tty, pw->pw_uid, gid) < 0) {
			if (errno == EROFS &&
			    (st.st_uid == pw->pw_uid || st.st_uid == 0))
				debug("chown(%.100s, %u, %u) failed: %.100s",
				    tty, (u_int)pw->pw_uid, (u_int)gid,
				    strerror(errno));
			else
				fatal("chown(%.100s, %u, %u) failed: %.100s",
				    tty, (u_int)pw->pw_uid, (u_int)gid,
				    strerror(errno));
		}
	}

	if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) {
		if (chmod(tty, mode) < 0) {
			if (errno == EROFS &&
			    (st.st_mode & (S_IRGRP | S_IROTH)) == 0)
				debug("chmod(%.100s, 0%o) failed: %.100s",
				    tty, (u_int)mode, strerror(errno));
			else
				fatal("chmod(%.100s, 0%o) failed: %.100s",
				    tty, (u_int)mode, strerror(errno));
		}
	}
}

/* Disconnect from the controlling tty. */
void
disconnect_controlling_tty(void)
{
#ifdef TIOCNOTTY
	int fd;

	if ((fd = open(_PATH_TTY, O_RDWR | O_NOCTTY)) >= 0) {
		(void) ioctl(fd, TIOCNOTTY, NULL);
		close(fd);
	}
#endif /* TIOCNOTTY */
}
