2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-09-04 16:25:25 +00:00

Break out pty code into pty.c

This commit is contained in:
Todd C. Miller
2009-10-16 13:29:38 +00:00
parent e443ee9ff4
commit 9544845ef8
4 changed files with 191 additions and 132 deletions

2
configure vendored
View File

@@ -25613,7 +25613,7 @@ echo "${ECHO_T}$enable_transcript" >&6; }
if test "${enable_transcript-yes}" != "no"; then if test "${enable_transcript-yes}" != "no"; then
SUDO_OBJS="${SUDO_OBJS} script.o" SUDO_OBJS="${SUDO_OBJS} pty.o script.o"
PROGS="$PROGS sudoreplay" PROGS="$PROGS sudoreplay"
REPLAY="" REPLAY=""
fi fi

View File

@@ -2594,10 +2594,10 @@ SUDO_TIMEDIR
SUDO_TRANSCRIPT SUDO_TRANSCRIPT
dnl dnl
dnl If transcript is enabled, build sudoreplay and add script.o for sudo dnl If transcript is enabled, build sudoreplay and add pty.o script.o for sudo
dnl dnl
if test "${enable_transcript-yes}" != "no"; then if test "${enable_transcript-yes}" != "no"; then
SUDO_OBJS="${SUDO_OBJS} script.o" SUDO_OBJS="${SUDO_OBJS} pty.o script.o"
PROGS="$PROGS sudoreplay" PROGS="$PROGS sudoreplay"
REPLAY="" REPLAY=""
fi fi

184
pty.c Normal file
View File

@@ -0,0 +1,184 @@
/*
* Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <config.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#ifdef HAVE_SYS_STROPTS_H
#include <sys/stropts.h>
#endif /* HAVE_SYS_STROPTS_H */
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif /* STDC_HEADERS */
#ifdef HAVE_STRING_H
# include <string.h>
#else
# ifdef HAVE_STRINGS_H
# include <strings.h>
# endif
#endif /* HAVE_STRING_H */
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#ifdef HAVE_UTIL_H
# include <util.h>
#endif
#ifdef HAVE_PTY_H
# include <pty.h>
#endif
#include "sudo.h"
#ifndef lint
__unused static const char rcsid[] = "$Sudo$";
#endif /* lint */
#ifdef HAVE_OPENPTY
int
get_pty(master, slave, name, namesz)
int *master;
int *slave;
char *name;
size_t namesz;
{
struct group *gr;
gid_t ttygid = -1;
if ((gr = sudo_getgrnam("tty")) != NULL)
ttygid = gr->gr_gid;
if (openpty(master, slave, name, NULL, NULL) != 0)
return(0);
(void) chown(name, runas_pw->pw_uid, ttygid);
return(1);
}
#else
# ifdef HAVE_GRANTPT
# ifndef HAVE_POSIX_OPENPT
static int
posix_openpt(oflag)
int oflag;
{
int fd;
# ifdef _AIX
fd = open("/dev/ptc", oflag);
# else
fd = open("/dev/ptmx", oflag);
# endif
return(fd);
}
# endif /* HAVE_POSIX_OPENPT */
int
get_pty(master, slave, name, namesz)
int *master;
int *slave;
char *name;
size_t namesz;
{
char *line;
*master = posix_openpt(O_RDWR|O_NOCTTY);
if (*master == -1)
return(0);
(void) grantpt(*master);
if (unlockpt(*master) != 0) {
close(*master);
return(0);
}
line = ptsname(*master);
if (line == NULL) {
close(*master);
return(0);
}
*slave = open(line, O_RDWR|O_NOCTTY, 0);
if (*slave == -1) {
close(*master);
return(0);
}
#ifdef I_PUSH
ioctl(*slave, I_PUSH, "ptem"); /* pseudo tty emulation module */
ioctl(*slave, I_PUSH, "ldterm"); /* line discipline module */
#endif
(void) chown(line, runas_pw->pw_uid, -1);
strlcpy(name, line, namesz);
return(1);
}
# else /* !HAVE_GRANTPT */
static char line[] = "/dev/ptyXX";
int
get_pty(master, slave, name, namesz)
int *master;
int *slave;
char *name;
size_t namesz;
{
char *bank, *cp;
struct group *gr;
gid_t ttygid = -1;
if ((gr = sudo_getgrnam("tty")) != NULL)
ttygid = gr->gr_gid;
for (bank = "pqrs"; *bank != '\0'; bank++) {
line[sizeof("/dev/ptyX") - 2] = *bank;
for (cp = "0123456789abcdef"; *cp != '\0'; cp++) {
line[sizeof("/dev/ptyXX") - 2] = *cp;
*master = open(line, O_RDWR|O_NOCTTY, 0);
if (*master == -1) {
if (errno == ENOENT)
return(0); /* out of ptys */
continue; /* already in use */
}
line[sizeof("/dev/p") - 2] = 't';
(void) chown(line, runas_pw->pw_uid, ttygid);
(void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
# ifdef HAVE_REVOKE
(void) revoke(line);
# endif
*slave = open(line, O_RDWR|O_NOCTTY, 0);
if (*slave != -1) {
strlcpy(name, line, namesz);
return(1); /* success */
}
(void) close(*master);
}
}
return(0);
}
# endif /* HAVE_GRANTPT */
#endif /* HAVE_OPENPTY */

133
script.c
View File

@@ -22,9 +22,6 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#ifdef HAVE_SYS_STROPTS_H
#include <sys/stropts.h>
#endif /* HAVE_SYS_STROPTS_H */
#ifdef HAVE_SYS_SELECT_H #ifdef HAVE_SYS_SELECT_H
#include <sys/select.h> #include <sys/select.h>
#endif /* HAVE_SYS_SELECT_H */ #endif /* HAVE_SYS_SELECT_H */
@@ -59,13 +56,6 @@
#include <pwd.h> #include <pwd.h>
#include <signal.h> #include <signal.h>
#ifdef HAVE_UTIL_H
# include <util.h>
#endif
#ifdef HAVE_PTY_H
# include <pty.h>
#endif
#include "sudo.h" #include "sudo.h"
#ifndef lint #ifndef lint
@@ -93,11 +83,7 @@ static sig_atomic_t signo;
static pid_t parent, grandchild; static pid_t parent, grandchild;
static int grandchild_status; static int grandchild_status;
#if defined(HAVE_OPENPTY) || defined(HAVE_GRANTPT)
static char slavename[PATH_MAX]; static char slavename[PATH_MAX];
#else
static char slavename[] = "/dev/ptyXX";
#endif
static void script_child __P((char *path, char *argv[])); static void script_child __P((char *path, char *argv[]));
static void script_grandchild __P((char *path, char *argv[], int)); static void script_grandchild __P((char *path, char *argv[], int));
@@ -105,10 +91,11 @@ static void sync_winsize __P((int src, int dst));
static void handler __P((int s)); static void handler __P((int s));
static void sigchild __P((int s)); static void sigchild __P((int s));
static void sigwinch __P((int s)); static void sigwinch __P((int s));
static int get_pty __P((int *master, int *slave));
static void flush_output __P((struct script_buf *output, struct timeval *then, static void flush_output __P((struct script_buf *output, struct timeval *then,
struct timeval *now, FILE *ofile, FILE *tfile)); struct timeval *now, FILE *ofile, FILE *tfile));
extern int get_pty __P((int *master, int *slave, char *name, size_t namesz));
/* /*
* TODO: run monitor as root? * TODO: run monitor as root?
*/ */
@@ -238,7 +225,8 @@ script_setup()
if (!isatty(STDIN_FILENO)) if (!isatty(STDIN_FILENO))
log_error(0, "Standard input is not a tty"); log_error(0, "Standard input is not a tty");
if (!get_pty(&script_fds[SFD_MASTER], &script_fds[SFD_SLAVE])) if (!get_pty(&script_fds[SFD_MASTER], &script_fds[SFD_SLAVE],
slavename, sizeof(slavename)))
log_error(USE_ERRNO, "Can't get pty"); log_error(USE_ERRNO, "Can't get pty");
/* Copy terminal attrs from stdin -> pty slave. */ /* Copy terminal attrs from stdin -> pty slave. */
@@ -823,116 +811,3 @@ sigwinch(s)
sync_winsize(STDIN_FILENO, script_fds[SFD_SLAVE]); sync_winsize(STDIN_FILENO, script_fds[SFD_SLAVE]);
errno = serrno; errno = serrno;
} }
#ifdef HAVE_OPENPTY
static int
get_pty(master, slave)
int *master;
int *slave;
{
struct group *gr;
gid_t ttygid = -1;
if ((gr = sudo_getgrnam("tty")) != NULL)
ttygid = gr->gr_gid;
if (openpty(master, slave, slavename, NULL, NULL) != 0)
return(0);
(void) chown(slavename, runas_pw->pw_uid, ttygid);
return(1);
}
#else
# ifdef HAVE_GRANTPT
# ifndef HAVE_POSIX_OPENPT
static int
posix_openpt(oflag)
int oflag;
{
int fd;
# ifdef _AIX
fd = open("/dev/ptc", oflag);
# else
fd = open("/dev/ptmx", oflag);
# endif
return(fd);
}
# endif /* HAVE_POSIX_OPENPT */
static int
get_pty(master, slave)
int *master;
int *slave;
{
char *line;
*master = posix_openpt(O_RDWR|O_NOCTTY);
if (*master == -1)
return(0);
(void) grantpt(*master);
if (unlockpt(*master) != 0) {
close(*master);
return(0);
}
line = ptsname(*master);
if (line == NULL) {
close(*master);
return(0);
}
strlcpy(slavename, line, sizeof(slavename));
*slave = open(slavename, O_RDWR|O_NOCTTY, 0);
if (*slave == -1) {
close(*master);
return(0);
}
#ifdef I_PUSH
ioctl(*slave, I_PUSH, "ptem"); /* pseudo tty emulation module */
ioctl(*slave, I_PUSH, "ldterm"); /* line discipline module */
#endif
(void) chown(slavename, runas_pw->pw_uid, -1);
return(1);
}
# else /* !HAVE_GRANTPT */
static int
get_pty(master, slave)
int *master;
int *slave;
{
char *bank, *cp;
struct group *gr;
gid_t ttygid = -1;
if ((gr = sudo_getgrnam("tty")) != NULL)
ttygid = gr->gr_gid;
for (bank = "pqrs"; *bank != '\0'; bank++) {
slavename[sizeof("/dev/ptyX") - 2] = *bank;
for (cp = "0123456789abcdef"; *cp != '\0'; cp++) {
slavename[sizeof("/dev/ptyXX") - 2] = *cp;
*master = open(slavename, O_RDWR|O_NOCTTY, 0);
if (*master == -1) {
if (errno == ENOENT)
return(0); /* out of ptys */
continue; /* already in use */
}
slavename[sizeof("/dev/p") - 2] = 't';
(void) chown(slavename, runas_pw->pw_uid, ttygid);
(void) chmod(slavename, S_IRUSR|S_IWUSR|S_IWGRP);
# ifdef HAVE_REVOKE
(void) revoke(slavename);
# endif
*slave = open(slavename, O_RDWR|O_NOCTTY, 0);
if (*slave != -1)
return(1); /* success */
(void) close(*master);
}
}
return(0);
}
# endif /* HAVE_GRANTPT */
#endif /* HAVE_OPENPTY */