openbsd-ports/japanese/kterm/patches/patch-main_c
pvalchev 735abcecdf Treat this much like XF4 xterm got treated based on the work on Matthieu
and Theo:
- Revoke root privileges early (root needed for pty allocation)
- Make it setgid utmp in order to update utmp with root privileges
revoked.  utmp also revoked if not needed (-u used for ex)
2002-11-21 05:41:14 +00:00

495 lines
13 KiB
Plaintext

$OpenBSD: patch-main_c,v 1.2 2002/11/21 05:41:14 pvalchev Exp $
--- main.c.orig Wed Nov 20 00:27:51 2002
+++ main.c Wed Nov 20 01:02:33 2002
@@ -142,9 +142,16 @@ static Bool IsPts = False;
#define WTMP
#endif
+#ifdef CSRG_BASED
+#define USE_POSIX_TERMIOS
+#endif
+
#include <sys/ioctl.h>
#include <sys/stat.h>
+#ifdef USE_POSIX_TERMIOS
+#include <termios.h>
+#else
#ifdef USE_TERMIOS
#include <termios.h>
/* this hacked termios support only works on SYSV */
@@ -159,10 +166,12 @@ static Bool IsPts = False;
#include <sys/termio.h>
#endif /* SYSV */
#endif /* USE_TERMIOS else */
+#endif /* USE_POSIX_TERMIOS */
#ifdef SVR4
#undef TIOCSLTC /* defined, but not useable */
#endif
+#define USE_TERMCAP_ENVVARS /* every one uses this except SYSV maybe */
#if defined(__sgi) && OSMAJORVERSION >= 5
#undef TIOCLSET /* defined, but not useable */
@@ -225,7 +234,9 @@ static Bool IsPts = False;
#endif
#else /* } !SYSV { */ /* BSD systems */
#ifndef linux
+#ifndef USE_POSIX_TERMIOS
#include <sgtty.h>
+#endif /* USE_POSIX_TERMIOS */
#endif
#include <sys/resource.h>
#define HAS_UTMP_UT_HOST
@@ -236,6 +247,10 @@ static Bool IsPts = False;
#endif
#endif /* } !SYSV */
+#ifdef USE_TTY_GROUP
+#include <grp.h>
+#endif
+
#ifdef _POSIX_SOURCE
#define USE_POSIX_WAIT
#define HAS_POSIX_SAVED_IDS
@@ -251,6 +266,8 @@ static Bool IsPts = False;
#if (BSD >= 199103)
#define USE_POSIX_WAIT
+#define LASTLOG
+#define WTMP
#define HAS_POSIX_SAVED_IDS
#endif
@@ -301,6 +318,10 @@ extern struct utmp *getutid __((struct u
int Ptyfd;
#endif /* PUCC_PTYD */
+#ifdef __OpenBSD__
+#include <util.h>
+#endif
+
#ifdef sequent
#define USE_GET_PSEUDOTTY
#endif
@@ -362,6 +383,10 @@ int Ptyfd;
#define SIGNAL_RETURN return
#endif
+#ifndef TTY_GROUP_NAME
+#define TTY_GROUP_NAME "tty"
+#endif
+
SIGNAL_T Exit();
#ifndef X_NOT_POSIX
@@ -407,6 +432,10 @@ static Bool added_utmp_entry = False;
static Bool xterm_exiting = False;
+#ifdef __OpenBSD__
+static gid_t utmpGid = -1;
+#endif
+
/*
** Ordinarily it should be okay to omit the assignment in the following
** statement. Apparently the c89 compiler on AIX 4.1.3 has a bug, or does
@@ -416,6 +445,9 @@ static Bool xterm_exiting = False;
*/
static char **command_to_exec = NULL;
+static int get_pty (int *pty);
+static void set_owner (char *device, int uid, int gid, int mode);
+
#ifdef USE_SYSV_TERMIO
/* The following structures are initialized in main() in order
** to eliminate any assumptions about the internal order of their
@@ -434,6 +466,9 @@ static struct ltchars d_ltc;
static unsigned int d_lmode;
#endif /* TIOCLSET */
#else /* not USE_SYSV_TERMIO */
+#ifdef USE_POSIX_TERMIOS
+static struct termios d_tio;
+#else /* not USE_POSIX_TERMIOS */
static struct sgttyb d_sg = {
0, 0, 0177, CKILL, EVENP|ODDP|ECHO|XTABS|CRMOD
};
@@ -457,6 +492,7 @@ static struct jtchars d_jtc = {
'J', 'B'
};
#endif /* sony */
+#endif /* USE_POSIX_TERMIOS */
#endif /* USE_SYSV_TERMIO */
/* allow use of system default characters if defined and reasonable */
@@ -1107,37 +1143,47 @@ char **argv;
char *base_name();
int xerror(), xioerror();
- XtSetLanguageProc (NULL, NULL, NULL);
-
ProgramName = argv[0];
/* +2 in case longer tty name like /dev/ttyq255 */
- ttydev = (char *) malloc (sizeof(TTYDEV) + 2);
+ ttydev = (char *) malloc (sizeof(TTYDEV) + 80);
#ifndef __osf__
- ptydev = (char *) malloc (sizeof(PTYDEV) + 2);
+ ptydev = (char *) malloc (sizeof(PTYDEV) + 80);
if (!ttydev || !ptydev)
#else
if (!ttydev)
#endif
{
- fprintf (stderr,
- "%s: unable to allocate memory for ttydev or ptydev\n",
- ProgramName);
- exit (1);
+ fprintf(stderr,
+ "%s: unable to allocate memory for ttydev or ptydev\n",
+ ProgramName);
+ exit (1);
}
strcpy (ttydev, TTYDEV);
#ifndef __osf__
strcpy (ptydev, PTYDEV);
#endif
-#ifdef USE_SYSV_TERMIO /* { */
+#ifdef __OpenBSD__
+ get_pty(NULL);
+ seteuid(getuid());
+ setuid(getuid());
+#endif /* __OpenBSD__ */
+
+ XtSetLanguageProc (NULL, NULL, NULL);
+
+#if defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS) /* { */
/* Initialization is done here rather than above in order
** to prevent any assumptions about the order of the contents
** of the various terminal structures (which may change from
** implementation to implementation).
*/
d_tio.c_iflag = ICRNL|IXON;
+#ifdef TAB3
d_tio.c_oflag = OPOST|ONLCR|TAB3;
+#else
+ d_tio.c_oflag = OPOST|ONLCR;
+#endif
#if defined(macII) || defined(ATT) || defined(CRAY) /* { */
d_tio.c_cflag = B9600|CS8|CREAD|PARENB|HUPCL;
d_tio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
@@ -1161,9 +1207,11 @@ char **argv;
d_tio.c_cc[VEOL2] = CNUL;
d_tio.c_cc[VSWTCH] = CNUL;
-#ifdef USE_TERMIOS /* { */
+#if defined(USE_TERMIOS) || defined(USE_POSIX_TERMIOS) /* { */
d_tio.c_cc[VSUSP] = CSUSP;
+#ifdef VDSUSP
d_tio.c_cc[VDSUSP] = CDSUSP;
+#endif
d_tio.c_cc[VREPRINT] = CRPRNT;
d_tio.c_cc[VDISCARD] = CFLUSH;
d_tio.c_cc[VWERASE] = CWERASE;
@@ -1181,11 +1229,17 @@ char **argv;
d_lmode = 0;
#endif /* } TIOCLSET */
#else /* }{ else !macII, ATT, CRAY */
+#ifndef USE_POSIX_TERMIOS
#ifdef BAUD_0 /* { */
d_tio.c_cflag = CS8|CREAD|PARENB|HUPCL;
#else /* }{ !BAUD_0 */
d_tio.c_cflag = B9600|CS8|CREAD|PARENB|HUPCL;
#endif /* } !BAUD_0 */
+#else /* USE_POSIX_TERMIOS */
+ d_tio.c_cflag = CS8|CREAD|PARENB|HUPCL;
+ cfsetispeed(&d_tio, B9600);
+ cfsetospeed(&d_tio, B9600);
+#endif
d_tio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
#ifdef ECHOKE
d_tio.c_lflag |= ECHOKE|IEXTEN;
@@ -1193,11 +1247,13 @@ char **argv;
#ifdef ECHOCTL
d_tio.c_lflag |= ECHOCTL|IEXTEN;
#endif
+#ifndef USE_POSIX_TERMIOS
#ifdef NTTYDISC
d_tio.c_line = NTTYDISC;
#else
d_tio.c_line = 0;
#endif
+#endif /* USE_POSIX_TERMIOS */
#ifdef __sgi
d_tio.c_cflag &= ~(HUPCL|PARENB);
d_tio.c_iflag |= BRKINT|ISTRIP|IGNPAR;
@@ -1246,8 +1302,14 @@ char **argv;
int i;
for (i = 0; i <= 2; i++) {
+#ifndef USE_POSIX_TERMIOS
struct termio deftio;
- if (ioctl (i, TCGETA, &deftio) == 0) {
+ if (ioctl (i, TCGETA, &deftio) == 0)
+#else
+ struct termios deftio;
+ if (tcgetattr(i, &deftio) == 0)
+#endif
+ {
d_tio.c_cc[VINTR] = deftio.c_cc[VINTR];
d_tio.c_cc[VQUIT] = deftio.c_cc[VQUIT];
d_tio.c_cc[VERASE] = deftio.c_cc[VERASE];
@@ -1302,9 +1364,11 @@ char **argv;
d_ltc.t_werasc = '\377';
d_ltc.t_lnextc = '\377';
#endif /* } TIOCSLTC */
-#ifdef USE_TERMIOS /* { */
+#if defined(USE_TERMIOS) || defined(USE_POSIX_TERMIOS) /* { */
d_tio.c_cc[VSUSP] = CSUSP;
+#ifdef VDSUSP
d_tio.c_cc[VDSUSP] = '\000';
+#endif
d_tio.c_cc[VREPRINT] = '\377';
d_tio.c_cc[VDISCARD] = '\377';
d_tio.c_cc[VWERASE] = '\377';
@@ -1361,6 +1425,14 @@ char **argv;
(void) fprintf(stderr, "setegid(%d): %s\n",
(int) egid, strerror(errno));
#endif
+
+#ifdef __OpenBSD__
+ if (resource.utmpInhibit) {
+ /* Can totally revoke group privs */
+ setegid(getgid());
+ setgid(getgid());
+ }
+#endif
}
waiting_for_initial_map = resource.wait_for_map;
@@ -1719,6 +1791,32 @@ char *name;
get_pty (pty)
int *pty;
{
+#ifdef __OpenBSD__
+ int result;
+ static int m_tty = -1;
+ static int m_pty = -1;
+ struct group *ttygrp;
+
+ if (pty == NULL) {
+ result = openpty(&m_pty, &m_tty, ttydev, NULL, NULL);
+
+ seteuid(0);
+ if ((ttygrp = getgrnam(TTY_GROUP_NAME)) != 0) {
+ set_owner(ttydev, getuid(), ttygrp->gr_gid,
+ 0600);
+ } else {
+ set_owner(ttydev, getuid(), getgid(),
+ 0600);
+ }
+ seteuid(getuid());
+ return result;
+ } else if (m_pty != -1) {
+ *pty = m_pty;
+ return (0);
+ } else {
+ return (-1);
+ }
+#endif /* __OpenBSD__ */
#ifdef __osf__
int tty;
return (openpty(pty, &tty, ttydev, NULL, NULL));
@@ -2034,6 +2132,18 @@ void first_map_occurred ()
}
#endif /* USE_HANDSHAKE else !USE_HANDSHAKE */
+static void
+set_owner(char *device, int uid, int gid, int mode)
+{
+ if (chown (device, uid, gid) < 0) {
+ if (errno != ENOENT
+ && getuid() == 0) {
+ fprintf(stderr, "Cannot chown %s to %d,%d: %s\n",
+ device, uid, gid, strerror(errno));
+ }
+ }
+ chmod (device, mode);
+}
spawn ()
/*
@@ -2065,6 +2175,9 @@ spawn ()
int zero = 0;
int status;
#else /* else not USE_SYSV_TERMIO */
+#ifdef USE_POSIX_TERMIOS
+ struct termios tio;
+#else /* else not USE_POSIX_TERMIOS */
unsigned lmode;
struct tchars tc;
struct ltchars ltc;
@@ -2073,6 +2186,7 @@ spawn ()
int jmode;
struct jtchars jtc;
#endif /* sony */
+#endif /* USE_POSIX_TERMIOS */
#endif /* USE_SYSV_TERMIO */
char termcap [1024];
@@ -2168,9 +2282,9 @@ spawn ()
#ifdef TIOCLSET
lmode = d_lmode;
#endif /* TIOCLSET */
-#ifdef USE_SYSV_TERMIO
+#if defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS)
tio = d_tio;
-#else /* not USE_SYSV_TERMIO */
+#else /* not USE_SYSV_TERMIO and not USE_POSIX_TERMIOS */
sg = d_sg;
tc = d_tc;
discipline = d_disipline;
@@ -2178,7 +2292,7 @@ spawn ()
jmode = d_jmode;
jtc = d_jtc;
#endif /* sony */
-#endif /* USE_SYSV_TERMIO */
+#endif /* USE_SYSV_TERMIO or USE_POSIX_TERMIOS */
} else {
SysError(ERROR_OPDEVTTY);
}
@@ -2202,6 +2316,10 @@ spawn ()
tio = d_tio;
#else /* not USE_SYSV_TERMIO */
+#ifdef USE_POSIX_TERMIOS
+ if (tcgetattr(tty, &tio) == -1)
+ tio = d_tio;
+#else /* not USE_POSIX_TERMIOS */
if(ioctl(tty, TIOCGETP, (char *)&sg) == -1)
sg = d_sg;
if(ioctl(tty, TIOCGETC, (char *)&tc) == -1)
@@ -2214,6 +2332,7 @@ spawn ()
if(ioctl(tty, TIOCKGETC, (char *)&jtc) == -1)
jtc = d_jtc;
#endif /* sony */
+#endif /* USE_POSIX_TERMIOS */
#endif /* USE_SYSV_TERMIO */
close (tty);
/* tty is no longer an open fd! */
@@ -2507,6 +2626,7 @@ spawn ()
break;
#endif /* USE_SYSV_PGRP */
}
+ perror("open ttydev");
#ifdef TIOCSCTTY
ioctl(tty, TIOCSCTTY, 0);
@@ -2555,7 +2675,6 @@ spawn ()
#ifdef USE_TTY_GROUP
{
-#include <grp.h>
struct group *ttygrp;
if (ttygrp = getgrnam("tty")) {
/* change ownership of tty to real uid, "tty" gid */
@@ -2581,7 +2700,7 @@ spawn ()
* set up the tty modes
*/
{
-#ifdef USE_SYSV_TERMIO
+#if defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS)
#if defined(umips) || defined(CRAY) || defined(linux)
/* If the control tty had its modes screwed around with,
eg. by lineedit in the shell, or emacs, etc. then tio
@@ -2598,12 +2717,15 @@ spawn ()
tio.c_iflag &= ~(INLCR|IGNCR);
tio.c_iflag |= ICRNL;
/* ouput: cr->cr, nl is not return, no delays, ln->cr/nl */
+#ifndef USE_POSIX_TERMIOS
tio.c_oflag &=
~(OCRNL|ONLRET|NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
+#endif /* USE_POSIX_TERMIOS */
tio.c_oflag |= ONLCR;
#ifdef OPOST
tio.c_oflag |= OPOST;
#endif /* OPOST */
+#ifndef USE_POSIX_TERMIOS
#ifdef BAUD_0
/* baud rate is 0 (don't care) */
tio.c_cflag &= ~(CBAUD);
@@ -2612,6 +2734,13 @@ spawn ()
tio.c_cflag &= ~(CBAUD);
tio.c_cflag |= B9600;
#endif /* !BAUD_0 */
+#else /* USE_POSIX_TERMIOS */
+ cfsetispeed(&tio, B9600);
+ cfsetospeed(&tio, B9600);
+ /* Clear CLOCAL so that SIGHUP is sent to us
+ when the xterm ends */
+ tio.c_cflag &= ~CLOCAL;
+#endif /* USE_POSIX_TERMIOS */
tio.c_cflag &= ~CSIZE;
if (screen->input_eight_bits)
tio.c_cflag |= CS8;
@@ -2723,9 +2852,14 @@ spawn ()
if (ioctl (tty, TIOCLSET, (char *)&lmode) == -1)
HsSysError(cp_pipe[1], ERROR_TIOCLSET);
#endif /* TIOCLSET */
+#ifndef USE_POSIX_TERMIOS
if (ioctl (tty, TCSETA, &tio) == -1)
HsSysError(cp_pipe[1], ERROR_TIOCSETP);
-#else /* USE_SYSV_TERMIO */
+#else /* USE_POSIX_TERMIOS */
+ if (tcsetattr (tty, TCSANOW, &tio) == -1)
+ HsSysError(cp_pipe[1], ERROR_TIOCSETP);
+#endif /* USE_POSIX_TERMIOS */
+#else /* USE_SYSV_TERMIO or USE_POSIX_TERMIOS */
#ifdef KTERM
sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW
| EVENP | ODDP);
@@ -3100,6 +3234,15 @@ spawn ()
close(i);
}
#endif /* LASTLOG */
+
+#ifdef __OpenBSD__
+ /* Switch to real gid after writing utmp entry */
+ utmpGid = getegid();
+ if (getgid() != getegid()) {
+ utmpGid = getegid();
+ setegid(getgid());
+ }
+#endif
} else
tslot = -tslot;
}
@@ -3272,11 +3415,11 @@ spawn ()
shname_minus = malloc(strlen(shname) + 2);
(void) strcpy(shname_minus, "-");
(void) strcat(shname_minus, shname);
-#ifndef USE_SYSV_TERMIO
+#if !defined(USE_SYSV_TERMIO) && !defined(USE_POSIX_TERMIOS)
ldisc = XStrCmp("csh", shname + strlen(shname) - 3) == 0 ?
NTTYDISC : 0;
ioctl(0, TIOCSETD, (char *)&ldisc);
-#endif /* !USE_SYSV_TERMIO */
+#endif /* !USE_SYSV_TERMIO && !USE_POSIX_TERMIOS */
#ifdef USE_LOGIN_DASH_P
if (term->misc.login_shell && pw && added_utmp_entry)
@@ -3459,6 +3602,12 @@ Exit(n)
&& added_utmp_entry
#endif /* USE_HANDSHAKE */
) {
+#ifdef __OpenBSD__
+ if (utmpGid != -1) {
+ /* Switch back to group utmp */
+ setegid(utmpGid);
+ }
+#endif
ptyname = ttydev;
utmp.ut_type = USER_PROCESS;
if (PTYCHARLEN >= (int)strlen(ptyname))