[BACK]Return to sys_term.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / libexec / telnetd

Annotation of src/libexec/telnetd/sys_term.c, Revision 1.44

1.44    ! hubertf     1: /*     $NetBSD: sys_term.c,v 1.43 2005/05/05 01:28:57 lukem Exp $      */
1.8       thorpej     2:
1.1       cgd         3: /*
1.3       cgd         4:  * Copyright (c) 1989, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
1.39      agc        15:  * 3. Neither the name of the University nor the names of its contributors
1.1       cgd        16:  *    may be used to endorse or promote products derived from this software
                     17:  *    without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  */
                     31:
1.11      mrg        32: #include <sys/cdefs.h>
1.1       cgd        33: #ifndef lint
1.8       thorpej    34: #if 0
                     35: static char sccsid[] = "@(#)sys_term.c 8.4+1 (Berkeley) 5/30/95";
                     36: #else
1.44    ! hubertf    37: __RCSID("$NetBSD: sys_term.c,v 1.43 2005/05/05 01:28:57 lukem Exp $");
1.8       thorpej    38: #endif
1.1       cgd        39: #endif /* not lint */
                     40:
                     41: #include "telnetd.h"
                     42: #include "pathnames.h"
                     43:
1.11      mrg        44: #include <util.h>
1.41      christos   45: #include <vis.h>
1.11      mrg        46:
1.31      wiz        47: #include <utmp.h>
1.1       cgd        48: struct utmp wtmp;
                     49:
                     50: #define SCPYN(a, b)    (void) strncpy(a, b, sizeof(a))
                     51: #define SCMPN(a, b)    strncmp(a, b, sizeof(a))
                     52:
                     53: struct termios termbuf, termbuf2;      /* pty control structure */
                     54:
1.42      perry      55: void getptyslave(void);
                     56: int cleanopen(char *);
                     57: char **addarg(char **, char *);
                     58: void scrub_env(void);
                     59: int getent(char *, char *);
                     60: char *getstr(const char *, char **);
1.16      aidan      61: #ifdef KRB5
1.42      perry      62: extern void kerberos5_cleanup(void);
1.16      aidan      63: #endif
1.11      mrg        64:
1.1       cgd        65: /*
                     66:  * init_termbuf()
                     67:  * copy_termbuf(cp)
                     68:  * set_termbuf()
                     69:  *
                     70:  * These three routines are used to get and set the "termbuf" structure
                     71:  * to and from the kernel.  init_termbuf() gets the current settings.
                     72:  * copy_termbuf() hands in a new "termbuf" to write to the kernel, and
                     73:  * set_termbuf() writes the structure into the kernel.
                     74:  */
                     75:
1.36      itojun     76: void
1.42      perry      77: init_termbuf(void)
1.1       cgd        78: {
                     79:        (void) tcgetattr(pty, &termbuf);
                     80:        termbuf2 = termbuf;
                     81: }
                     82:
                     83: #if    defined(LINEMODE) && defined(TIOCPKT_IOCTL)
1.36      itojun     84: void
1.42      perry      85: copy_termbuf(char *cp, int len)
1.1       cgd        86: {
                     87:        if (len > sizeof(termbuf))
                     88:                len = sizeof(termbuf);
1.6       jtk        89:        memmove((char *)&termbuf, cp, len);
1.1       cgd        90:        termbuf2 = termbuf;
                     91: }
                     92: #endif /* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */
                     93:
1.36      itojun     94: void
1.42      perry      95: set_termbuf(void)
1.1       cgd        96: {
                     97:        /*
                     98:         * Only make the necessary changes.
                     99:         */
1.6       jtk       100:        if (memcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf)))
1.1       cgd       101:                (void) tcsetattr(pty, TCSANOW, &termbuf);
                    102: }
                    103:
                    104:
                    105: /*
                    106:  * spcset(func, valp, valpp)
                    107:  *
                    108:  * This function takes various special characters (func), and
                    109:  * sets *valp to the current value of that character, and
                    110:  * *valpp to point to where in the "termbuf" structure that
                    111:  * value is kept.
                    112:  *
                    113:  * It returns the SLC_ level of support for this function.
                    114:  */
                    115:
                    116:
1.36      itojun    117: int
1.42      perry     118: spcset(int func, cc_t *valp, cc_t **valpp)
1.1       cgd       119: {
                    120:
                    121: #define        setval(a, b)    *valp = termbuf.c_cc[a]; \
                    122:                        *valpp = &termbuf.c_cc[a]; \
                    123:                        return(b);
                    124: #define        defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT);
                    125:
                    126:        switch(func) {
                    127:        case SLC_EOF:
                    128:                setval(VEOF, SLC_VARIABLE);
                    129:        case SLC_EC:
                    130:                setval(VERASE, SLC_VARIABLE);
                    131:        case SLC_EL:
                    132:                setval(VKILL, SLC_VARIABLE);
                    133:        case SLC_IP:
                    134:                setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
                    135:        case SLC_ABORT:
                    136:                setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
                    137:        case SLC_XON:
                    138:                setval(VSTART, SLC_VARIABLE);
                    139:        case SLC_XOFF:
                    140:                setval(VSTOP, SLC_VARIABLE);
                    141:        case SLC_EW:
                    142:                setval(VWERASE, SLC_VARIABLE);
                    143:        case SLC_RP:
                    144:                setval(VREPRINT, SLC_VARIABLE);
                    145:        case SLC_LNEXT:
                    146:                setval(VLNEXT, SLC_VARIABLE);
                    147:        case SLC_AO:
                    148:                setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);
                    149:        case SLC_SUSP:
                    150:                setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN);
                    151:        case SLC_FORW1:
                    152:                setval(VEOL, SLC_VARIABLE);
                    153:        case SLC_FORW2:
                    154:                setval(VEOL2, SLC_VARIABLE);
                    155:        case SLC_AYT:
                    156:                setval(VSTATUS, SLC_VARIABLE);
                    157:
                    158:        case SLC_BRK:
                    159:        case SLC_SYNCH:
                    160:        case SLC_EOR:
                    161:                defval(0);
                    162:
                    163:        default:
                    164:                *valp = 0;
                    165:                *valpp = 0;
                    166:                return(SLC_NOSUPPORT);
                    167:        }
                    168: }
                    169:
                    170:
                    171: /*
                    172:  * getpty()
                    173:  *
                    174:  * Allocate a pty.  As a side effect, the external character
                    175:  * array "line" contains the name of the slave side.
                    176:  *
                    177:  * Returns the file descriptor of the opened pty.
                    178:  */
                    179: #ifndef        __GNUC__
1.19      christos  180: char *line = NULL16STR;
1.1       cgd       181: #else
1.19      christos  182: static char Xline[] = NULL16STR;
1.1       cgd       183: char *line = Xline;
                    184: #endif
                    185:
1.13      perry     186:
                    187: static int ptyslavefd; /* for cleanopen() */
                    188:
                    189: int
1.42      perry     190: getpty(int *ptynum)
1.44    ! hubertf   191: {
1.13      perry     192:        int ptyfd;
                    193:
                    194:        ptyfd = openpty(ptynum, &ptyslavefd, line, NULL, NULL);
                    195:        if (ptyfd == 0)
                    196:                return *ptynum;
                    197:        ptyslavefd = -1;
                    198:        return (-1);
                    199: }
1.1       cgd       200:
                    201: #ifdef LINEMODE
                    202: /*
                    203:  * tty_flowmode()      Find out if flow control is enabled or disabled.
                    204:  * tty_linemode()      Find out if linemode (external processing) is enabled.
                    205:  * tty_setlinemod(on)  Turn on/off linemode.
                    206:  * tty_isecho()                Find out if echoing is turned on.
                    207:  * tty_setecho(on)     Enable/disable character echoing.
                    208:  * tty_israw()         Find out if terminal is in RAW mode.
                    209:  * tty_binaryin(on)    Turn on/off BINARY on input.
                    210:  * tty_binaryout(on)   Turn on/off BINARY on output.
                    211:  * tty_isediting()     Find out if line editing is enabled.
                    212:  * tty_istrapsig()     Find out if signal trapping is enabled.
                    213:  * tty_setedit(on)     Turn on/off line editing.
                    214:  * tty_setsig(on)      Turn on/off signal trapping.
                    215:  * tty_issofttab()     Find out if tab expansion is enabled.
                    216:  * tty_setsofttab(on)  Turn on/off soft tab expansion.
                    217:  * tty_islitecho()     Find out if typed control chars are echoed literally
                    218:  * tty_setlitecho()    Turn on/off literal echo of control chars
                    219:  * tty_tspeed(val)     Set transmit speed to val.
                    220:  * tty_rspeed(val)     Set receive speed to val.
                    221:  */
                    222:
                    223:
1.36      itojun    224: int
1.42      perry     225: tty_linemode(void)
1.1       cgd       226: {
                    227:        return(termbuf.c_lflag & EXTPROC);
                    228: }
                    229:
1.36      itojun    230: void
1.42      perry     231: tty_setlinemode(int on)
1.1       cgd       232: {
                    233:        set_termbuf();
                    234:        (void) ioctl(pty, TIOCEXT, (char *)&on);
                    235:        init_termbuf();
                    236: }
1.3       cgd       237: #endif /* LINEMODE */
1.1       cgd       238:
1.36      itojun    239: int
1.42      perry     240: tty_isecho(void)
1.1       cgd       241: {
                    242:        return (termbuf.c_lflag & ECHO);
                    243: }
1.3       cgd       244:
1.36      itojun    245: int
1.42      perry     246: tty_flowmode(void)
1.3       cgd       247: {
                    248:        return((termbuf.c_iflag & IXON) ? 1 : 0);
                    249: }
                    250:
1.36      itojun    251: int
1.42      perry     252: tty_restartany(void)
1.3       cgd       253: {
                    254:        return((termbuf.c_iflag & IXANY) ? 1 : 0);
                    255: }
1.1       cgd       256:
1.36      itojun    257: void
1.42      perry     258: tty_setecho(int on)
1.1       cgd       259: {
                    260:        if (on)
                    261:                termbuf.c_lflag |= ECHO;
                    262:        else
                    263:                termbuf.c_lflag &= ~ECHO;
                    264: }
                    265:
1.36      itojun    266: int
1.42      perry     267: tty_israw(void)
1.1       cgd       268: {
                    269:        return(!(termbuf.c_lflag & ICANON));
                    270: }
1.3       cgd       271:
1.36      itojun    272: void
1.42      perry     273: tty_binaryin(int on)
1.1       cgd       274: {
                    275:        if (on) {
                    276:                termbuf.c_iflag &= ~ISTRIP;
                    277:        } else {
                    278:                termbuf.c_iflag |= ISTRIP;
                    279:        }
                    280: }
                    281:
1.36      itojun    282: void
1.42      perry     283: tty_binaryout(int on)
1.1       cgd       284: {
                    285:        if (on) {
                    286:                termbuf.c_cflag &= ~(CSIZE|PARENB);
                    287:                termbuf.c_cflag |= CS8;
                    288:                termbuf.c_oflag &= ~OPOST;
                    289:        } else {
                    290:                termbuf.c_cflag &= ~CSIZE;
                    291:                termbuf.c_cflag |= CS7|PARENB;
                    292:                termbuf.c_oflag |= OPOST;
                    293:        }
                    294: }
                    295:
1.36      itojun    296: int
1.42      perry     297: tty_isbinaryin(void)
1.1       cgd       298: {
                    299:        return(!(termbuf.c_iflag & ISTRIP));
                    300: }
                    301:
1.36      itojun    302: int
1.42      perry     303: tty_isbinaryout(void)
1.1       cgd       304: {
                    305:        return(!(termbuf.c_oflag&OPOST));
                    306: }
                    307:
                    308: #ifdef LINEMODE
1.36      itojun    309: int
1.42      perry     310: tty_isediting(void)
1.1       cgd       311: {
                    312:        return(termbuf.c_lflag & ICANON);
                    313: }
                    314:
1.36      itojun    315: int
1.42      perry     316: tty_istrapsig(void)
1.1       cgd       317: {
                    318:        return(termbuf.c_lflag & ISIG);
                    319: }
                    320:
1.36      itojun    321: void
1.42      perry     322: tty_setedit(int on)
1.1       cgd       323: {
                    324:        if (on)
                    325:                termbuf.c_lflag |= ICANON;
                    326:        else
                    327:                termbuf.c_lflag &= ~ICANON;
                    328: }
                    329:
1.36      itojun    330: void
1.42      perry     331: tty_setsig(int on)
1.1       cgd       332: {
                    333:        if (on)
                    334:                termbuf.c_lflag |= ISIG;
                    335:        else
                    336:                termbuf.c_lflag &= ~ISIG;
                    337: }
                    338: #endif /* LINEMODE */
                    339:
1.36      itojun    340: int
1.42      perry     341: tty_issofttab(void)
1.1       cgd       342: {
                    343: # ifdef        OXTABS
                    344:        return (termbuf.c_oflag & OXTABS);
                    345: # endif
                    346: # ifdef        TABDLY
                    347:        return ((termbuf.c_oflag & TABDLY) == TAB3);
                    348: # endif
                    349: }
                    350:
1.36      itojun    351: void
1.42      perry     352: tty_setsofttab(int on)
1.1       cgd       353: {
                    354:        if (on) {
                    355: # ifdef        OXTABS
                    356:                termbuf.c_oflag |= OXTABS;
                    357: # endif
                    358: # ifdef        TABDLY
                    359:                termbuf.c_oflag &= ~TABDLY;
                    360:                termbuf.c_oflag |= TAB3;
                    361: # endif
                    362:        } else {
                    363: # ifdef        OXTABS
                    364:                termbuf.c_oflag &= ~OXTABS;
                    365: # endif
                    366: # ifdef        TABDLY
                    367:                termbuf.c_oflag &= ~TABDLY;
                    368:                termbuf.c_oflag |= TAB0;
                    369: # endif
                    370:        }
                    371: }
                    372:
1.36      itojun    373: int
1.42      perry     374: tty_islitecho(void)
1.1       cgd       375: {
                    376: # ifdef        ECHOCTL
                    377:        return (!(termbuf.c_lflag & ECHOCTL));
                    378: # endif
                    379: # ifdef        TCTLECH
                    380:        return (!(termbuf.c_lflag & TCTLECH));
                    381: # endif
                    382: # if   !defined(ECHOCTL) && !defined(TCTLECH)
                    383:        return (0);     /* assumes ctl chars are echoed '^x' */
                    384: # endif
                    385: }
                    386:
1.36      itojun    387: void
1.42      perry     388: tty_setlitecho(int on)
1.1       cgd       389: {
                    390: # ifdef        ECHOCTL
                    391:        if (on)
                    392:                termbuf.c_lflag &= ~ECHOCTL;
                    393:        else
                    394:                termbuf.c_lflag |= ECHOCTL;
                    395: # endif
                    396: # ifdef        TCTLECH
                    397:        if (on)
                    398:                termbuf.c_lflag &= ~TCTLECH;
                    399:        else
                    400:                termbuf.c_lflag |= TCTLECH;
                    401: # endif
                    402: }
                    403:
1.36      itojun    404: int
1.42      perry     405: tty_iscrnl(void)
1.1       cgd       406: {
                    407:        return (termbuf.c_iflag & ICRNL);
                    408: }
                    409:
1.36      itojun    410: void
1.42      perry     411: tty_tspeed(int val)
1.1       cgd       412: {
1.6       jtk       413:        cfsetospeed(&termbuf, val);
1.1       cgd       414: }
                    415:
1.36      itojun    416: void
1.42      perry     417: tty_rspeed(int val)
1.1       cgd       418: {
1.6       jtk       419:        cfsetispeed(&termbuf, val);
1.1       cgd       420: }
                    421:
                    422:
                    423:
                    424:
                    425: /*
                    426:  * getptyslave()
                    427:  *
                    428:  * Open the slave side of the pty, and do any initialization
                    429:  * that is necessary.  The return value is a file descriptor
                    430:  * for the slave side.
                    431:  */
1.22      christos  432: extern int def_tspeed, def_rspeed;
                    433:        extern int def_row, def_col;
                    434:
1.42      perry     435: void
                    436: getptyslave(void)
1.1       cgd       437: {
1.42      perry     438:        int t = -1;
1.1       cgd       439:
1.31      wiz       440: #ifdef LINEMODE
1.1       cgd       441:        int waslm;
1.31      wiz       442: #endif
1.1       cgd       443:        struct winsize ws;
                    444:        /*
                    445:         * Opening the slave side may cause initilization of the
                    446:         * kernel tty structure.  We need remember the state of
                    447:         *      if linemode was turned on
                    448:         *      terminal window size
                    449:         *      terminal speed
                    450:         * so that we can re-set them if we need to.
                    451:         */
1.31      wiz       452: #ifdef LINEMODE
1.1       cgd       453:        waslm = tty_linemode();
1.31      wiz       454: #endif
1.1       cgd       455:
                    456:        /*
                    457:         * Make sure that we don't have a controlling tty, and
                    458:         * that we are the session (process group) leader.
                    459:         */
                    460:        t = open(_PATH_TTY, O_RDWR);
                    461:        if (t >= 0) {
                    462:                (void) ioctl(t, TIOCNOTTY, (char *)0);
                    463:                (void) close(t);
                    464:        }
                    465:
                    466:
                    467:
                    468:        t = cleanopen(line);
                    469:        if (t < 0)
                    470:                fatalperror(net, line);
                    471:
1.3       cgd       472:
1.1       cgd       473:        /*
                    474:         * set up the tty modes as we like them to be.
                    475:         */
                    476:        init_termbuf();
                    477:        if (def_row || def_col) {
1.6       jtk       478:                memset((char *)&ws, 0, sizeof(ws));
1.1       cgd       479:                ws.ws_col = def_col;
                    480:                ws.ws_row = def_row;
                    481:                (void)ioctl(t, TIOCSWINSZ, (char *)&ws);
                    482:        }
                    483:
                    484:        /*
                    485:         * Settings for sgtty based systems
                    486:         */
                    487:
                    488:        /*
                    489:         * Settings for all other termios/termio based
                    490:         * systems, other than 4.4BSD.  In 4.4BSD the
                    491:         * kernel does the initial terminal setup.
                    492:         */
                    493:        tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600);
                    494:        tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600);
1.31      wiz       495: #ifdef LINEMODE
1.1       cgd       496:        if (waslm)
                    497:                tty_setlinemode(1);
1.31      wiz       498: #endif /* LINEMODE */
1.1       cgd       499:
                    500:        /*
                    501:         * Set the tty modes, and make this our controlling tty.
                    502:         */
                    503:        set_termbuf();
                    504:        if (login_tty(t) == -1)
                    505:                fatalperror(net, "login_tty");
                    506:        if (net > 2)
                    507:                (void) close(net);
1.3       cgd       508:        if (pty > 2) {
1.1       cgd       509:                (void) close(pty);
1.3       cgd       510:                pty = -1;
                    511:        }
1.1       cgd       512: }
                    513:
                    514: /*
                    515:  * Open the specified slave side of the pty,
                    516:  * making sure that we have a clean tty.
                    517:  */
1.36      itojun    518: int
1.42      perry     519: cleanopen(char *ttyline)
1.1       cgd       520: {
1.13      perry     521:        return ptyslavefd;
1.1       cgd       522: }
                    523:
                    524: /*
                    525:  * startslave(host)
                    526:  *
                    527:  * Given a hostname, do whatever
                    528:  * is necessary to startup the login process on the slave side of the pty.
                    529:  */
                    530:
                    531: /* ARGSUSED */
1.36      itojun    532: void
1.42      perry     533: startslave(char *host, int autologin, char *autoname)
1.1       cgd       534: {
1.42      perry     535:        int i;
1.1       cgd       536:
1.36      itojun    537: #ifdef AUTHENTICATION
1.1       cgd       538:        if (!autoname || !autoname[0])
                    539:                autologin = 0;
                    540:
                    541:        if (autologin < auth_level) {
                    542:                fatal(net, "Authorization failed");
                    543:                exit(1);
                    544:        }
                    545: #endif
                    546:
                    547:
                    548:        if ((i = fork()) < 0)
                    549:                fatalperror(net, "fork");
                    550:        if (i) {
                    551:        } else {
1.11      mrg       552:                getptyslave();
1.1       cgd       553:                start_login(host, autologin, autoname);
                    554:                /*NOTREACHED*/
                    555:        }
                    556: }
                    557:
                    558: char   *envinit[3];
                    559:
1.36      itojun    560: void
1.42      perry     561: init_env(void)
1.1       cgd       562: {
                    563:        char **envp;
                    564:
                    565:        envp = envinit;
1.11      mrg       566:        if ((*envp = getenv("TZ")))
1.1       cgd       567:                *envp++ -= 3;
                    568:        *envp = 0;
                    569:        environ = envinit;
                    570: }
                    571:
                    572:
                    573: /*
                    574:  * start_login(host)
                    575:  *
                    576:  * Assuming that we are now running as a child processes, this
                    577:  * function will turn us into the login process.
                    578:  */
1.22      christos  579: extern char *gettyname;
1.1       cgd       580:
1.36      itojun    581: void
1.42      perry     582: start_login(char *host, int autologin, char *name)
1.1       cgd       583: {
1.42      perry     584:        char **argv;
1.9       tls       585: #define        TABBUFSIZ       512
                    586:        char    defent[TABBUFSIZ];
                    587:        char    defstrs[TABBUFSIZ];
                    588: #undef TABBUFSIZ
1.23      itojun    589:        const char *loginprog = NULL;
1.41      christos  590:        extern struct sockaddr_storage from;
                    591:        char buf[sizeof(from) * 4 + 1];
1.1       cgd       592:
1.6       jtk       593:        scrub_env();
                    594:
1.1       cgd       595:        /*
1.41      christos  596:         * -a : pass on the address of the host.
1.1       cgd       597:         * -h : pass on name of host.
1.41      christos  598:         *      WARNING:  -h and -a are accepted by login
                    599:         *      if and only if getuid() == 0.
1.1       cgd       600:         * -p : don't clobber the environment (so terminal type stays set).
                    601:         *
                    602:         * -f : force this login, he has already been authenticated
                    603:         */
                    604:        argv = addarg(0, "login");
1.3       cgd       605:
1.41      christos  606:        argv = addarg(argv, "-a");
                    607:        (void)strvisx(buf, (const char *)(const void *)&from, sizeof(from),
                    608:            VIS_WHITE);
                    609:        argv = addarg(argv, buf);
                    610:
                    611:        argv = addarg(argv, "-h");
                    612:        argv = addarg(argv, host);
                    613:
1.1       cgd       614:        argv = addarg(argv, "-p");
1.6       jtk       615: #ifdef LINEMODE
                    616:        /*
                    617:         * Set the environment variable "LINEMODE" to either
                    618:         * "real" or "kludge" if we are operating in either
                    619:         * real or kludge linemode.
                    620:         */
                    621:        if (lmodetype == REAL_LINEMODE)
                    622:                setenv("LINEMODE", "real", 1);
                    623: # ifdef KLUDGELINEMODE
                    624:        else if (lmodetype == KLUDGE_LINEMODE || lmodetype == KLUDGE_OK)
                    625:                setenv("LINEMODE", "kludge", 1);
                    626: # endif
                    627: #endif
1.36      itojun    628: #ifdef SECURELOGIN
1.1       cgd       629:        /*
                    630:         * don't worry about the -f that might get sent.
                    631:         * A -s is supposed to override it anyhow.
                    632:         */
1.15      dean      633:        if (require_secure_login)
1.1       cgd       634:                argv = addarg(argv, "-s");
                    635: #endif
1.36      itojun    636: #ifdef AUTHENTICATION
1.1       cgd       637:        if (auth_level >= 0 && autologin == AUTH_VALID) {
                    638:                argv = addarg(argv, "-f");
1.5       mycroft   639:                argv = addarg(argv, "--");
1.3       cgd       640:                argv = addarg(argv, name);
1.1       cgd       641:        } else
                    642: #endif
                    643:        if (getenv("USER")) {
1.5       mycroft   644:                argv = addarg(argv, "--");
1.1       cgd       645:                argv = addarg(argv, getenv("USER"));
1.3       cgd       646:                /*
                    647:                 * Assume that login will set the USER variable
                    648:                 * correctly.  For SysV systems, this means that
                    649:                 * USER will no longer be set, just LOGNAME by
                    650:                 * login.  (The problem is that if the auto-login
                    651:                 * fails, and the user then specifies a different
                    652:                 * account name, he can get logged in with both
                    653:                 * LOGNAME and USER in his environment, but the
                    654:                 * USER value will be wrong.
                    655:                 */
                    656:                unsetenv("USER");
1.1       cgd       657:        }
1.9       tls       658:         if (getent(defent, gettyname) == 1) {
                    659:                 char *cp = defstrs;
                    660:
                    661:                 loginprog = getstr("lo", &cp);
                    662:         }
                    663:         if (loginprog == NULL)
                    664:                 loginprog = _PATH_LOGIN;
1.1       cgd       665:        closelog();
1.6       jtk       666:        /*
                    667:         * This sleep(1) is in here so that telnetd can
                    668:         * finish up with the tty.  There's a race condition
                    669:         * the login banner message gets lost...
                    670:         */
                    671:        sleep(1);
1.9       tls       672:         execv(loginprog, argv);
1.1       cgd       673:
1.25      wiz       674:         syslog(LOG_ERR, "%s: %m", loginprog);
1.9       tls       675:         fatalperror(net, loginprog);
1.1       cgd       676:        /*NOTREACHED*/
                    677: }
                    678:
1.42      perry     679: char **
                    680: addarg(char **argv, char *val)
1.1       cgd       681: {
1.42      perry     682:        char **cpp;
1.40      itojun    683:        char **nargv;
1.1       cgd       684:
                    685:        if (argv == NULL) {
                    686:                /*
                    687:                 * 10 entries, a leading length, and a null
                    688:                 */
                    689:                argv = (char **)malloc(sizeof(*argv) * 12);
                    690:                if (argv == NULL)
                    691:                        return(NULL);
                    692:                *argv++ = (char *)10;
                    693:                *argv = (char *)0;
                    694:        }
                    695:        for (cpp = argv; *cpp; cpp++)
                    696:                ;
1.7       jtk       697:        if (cpp == &argv[(long)argv[-1]]) {
1.1       cgd       698:                --argv;
1.40      itojun    699:                nargv = (char **)realloc(argv,
                    700:                    sizeof(*argv) * ((long)(*argv) + 10 + 2));
1.18      tron      701:                if (argv == NULL) {
                    702:                        fatal(net, "not enough memory");
                    703:                        /*NOTREACHED*/
                    704:                }
1.40      itojun    705:                argv = nargv;
                    706:                *argv = (char *)((long)(*argv) + 10);
1.1       cgd       707:                argv++;
1.7       jtk       708:                cpp = &argv[(long)argv[-1] - 10];
1.1       cgd       709:        }
                    710:        *cpp++ = val;
                    711:        *cpp = 0;
                    712:        return(argv);
                    713: }
                    714:
                    715: /*
1.6       jtk       716:  * scrub_env()
                    717:  *
1.20      assar     718:  * We only accept the environment variables listed below.
1.6       jtk       719:  */
1.20      assar     720:
1.11      mrg       721: void
1.42      perry     722: scrub_env(void)
1.6       jtk       723: {
1.20      assar     724:        static const char *reject[] = {
                    725:                "TERMCAP=/",
                    726:                NULL
                    727:        };
                    728:
1.27      wiz       729:        static const char *acceptstr[] = {
1.20      assar     730:                "XAUTH=", "XAUTHORITY=", "DISPLAY=",
                    731:                "TERM=",
                    732:                "EDITOR=",
                    733:                "PAGER=",
                    734:                "LOGNAME=",
                    735:                "POSIXLY_CORRECT=",
                    736:                "TERMCAP=",
                    737:                "PRINTER=",
                    738:                NULL
                    739:        };
                    740:
                    741:        char **cpp, **cpp2;
                    742:        const char **p;
1.6       jtk       743:
                    744:        for (cpp2 = cpp = environ; *cpp; cpp++) {
1.20      assar     745:                int reject_it = 0;
                    746:
                    747:                for(p = reject; *p; p++)
                    748:                        if(strncmp(*cpp, *p, strlen(*p)) == 0) {
                    749:                                reject_it = 1;
                    750:                                break;
                    751:                        }
                    752:                if (reject_it)
                    753:                        continue;
                    754:
1.27      wiz       755:                for(p = acceptstr; *p; p++)
1.20      assar     756:                        if(strncmp(*cpp, *p, strlen(*p)) == 0)
                    757:                                break;
                    758:                if(*p != NULL)
1.6       jtk       759:                        *cpp2++ = *cpp;
                    760:        }
1.20      assar     761:        *cpp2 = NULL;
1.6       jtk       762: }
                    763:
                    764: /*
1.1       cgd       765:  * cleanup()
                    766:  *
                    767:  * This is the routine to call when we are all through, to
                    768:  * clean up anything that needs to be cleaned up.
                    769:  */
1.36      itojun    770: /* ARGSUSED */
                    771: void
1.42      perry     772: cleanup(int sig)
1.1       cgd       773: {
1.14      tsarna    774:        char *p, c;
1.1       cgd       775:
1.43      lukem     776:        p = line + sizeof(_PATH_DEV) - 1;
1.32      christos  777: #ifdef SUPPORT_UTMP
1.1       cgd       778:        if (logout(p))
                    779:                logwtmp(p, "", "");
1.32      christos  780: #endif
                    781: #ifdef SUPPORT_UTMPX
                    782:        if (logoutx(p, 0, DEAD_PROCESS))
                    783:                logwtmpx(p, "", "", 0, DEAD_PROCESS);
                    784: #endif
1.1       cgd       785:        (void)chmod(line, 0666);
                    786:        (void)chown(line, 0, 0);
1.14      tsarna    787:        c = *p; *p = 'p';
1.1       cgd       788:        (void)chmod(line, 0666);
                    789:        (void)chown(line, 0, 0);
1.14      tsarna    790:        *p = c;
                    791:        if (ttyaction(line, "telnetd", "root"))
                    792:                syslog(LOG_ERR, "%s: ttyaction failed", line);
1.1       cgd       793:        (void) shutdown(net, 2);
                    794:        exit(1);
                    795: }

CVSweb <webmaster@jp.NetBSD.org>