Import NetBSD telnetd(8)
Change-Id: Ie1ae80e8a4945f6f4ccce8f468c1b04a8d89cf43
This commit is contained in:
parent
7348b5c52b
commit
e044bafaad
|
|
@ -1000,6 +1000,7 @@
|
||||||
./usr/libexec/ld.elf_so minix-base
|
./usr/libexec/ld.elf_so minix-base
|
||||||
./usr/libexec/makewhatis minix-base
|
./usr/libexec/makewhatis minix-base
|
||||||
./usr/libexec/rshd minix-base
|
./usr/libexec/rshd minix-base
|
||||||
|
./usr/libexec/telnetd minix-base
|
||||||
./usr/libexec/virecover minix-base
|
./usr/libexec/virecover minix-base
|
||||||
./usr/log minix-base
|
./usr/log minix-base
|
||||||
./usr/log/messages minix-base
|
./usr/log/messages minix-base
|
||||||
|
|
|
||||||
|
|
@ -591,6 +591,7 @@
|
||||||
./usr/libdata/debug/usr/libexec/lto1.debug minix-debug gcc=5,gcccmds,debug
|
./usr/libdata/debug/usr/libexec/lto1.debug minix-debug gcc=5,gcccmds,debug
|
||||||
./usr/libdata/debug/usr/libexec/makewhatis.debug minix-debug debug
|
./usr/libdata/debug/usr/libexec/makewhatis.debug minix-debug debug
|
||||||
./usr/libdata/debug/usr/libexec/rshd.debug minix-debug debug
|
./usr/libdata/debug/usr/libexec/rshd.debug minix-debug debug
|
||||||
|
./usr/libdata/debug/usr/libexec/telnetd.debug minix-debug debug
|
||||||
./usr/libdata/debug/usr/mdec minix-debug
|
./usr/libdata/debug/usr/mdec minix-debug
|
||||||
./usr/libdata/debug/usr/sbin minix-debug
|
./usr/libdata/debug/usr/sbin minix-debug
|
||||||
./usr/libdata/debug/usr/sbin/arp.debug minix-debug debug
|
./usr/libdata/debug/usr/sbin/arp.debug minix-debug debug
|
||||||
|
|
|
||||||
|
|
@ -3476,6 +3476,7 @@
|
||||||
./usr/man/man8/sysctl.8 minix-man
|
./usr/man/man8/sysctl.8 minix-man
|
||||||
./usr/man/man8/syslogd.8 minix-man
|
./usr/man/man8/syslogd.8 minix-man
|
||||||
./usr/man/man8/tcpd.8 minix-man obsolete
|
./usr/man/man8/tcpd.8 minix-man obsolete
|
||||||
|
./usr/man/man8/telnetd.8 minix-man
|
||||||
./usr/man/man8/traceroute.8 minix-man
|
./usr/man/man8/traceroute.8 minix-man
|
||||||
./usr/man/man8/traceroute6.8 minix-man use_inet6
|
./usr/man/man8/traceroute6.8 minix-man use_inet6
|
||||||
./usr/man/man8/uds.8 minix-man obsolete
|
./usr/man/man8/uds.8 minix-man obsolete
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,7 @@ SUBDIR= \
|
||||||
fingerd ftpd getty \
|
fingerd ftpd getty \
|
||||||
ld.elf_so \
|
ld.elf_so \
|
||||||
rshd \
|
rshd \
|
||||||
|
telnetd
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.if defined(__MINIX)
|
.if defined(__MINIX)
|
||||||
SUBDIR+= makewhatis
|
SUBDIR+= makewhatis
|
||||||
|
|
|
||||||
43
libexec/telnetd/Makefile
Normal file
43
libexec/telnetd/Makefile
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
# $NetBSD: Makefile,v 1.49 2012/01/09 16:36:48 christos Exp $
|
||||||
|
# from: @(#)Makefile 8.2 (Berkeley) 12/15/93
|
||||||
|
|
||||||
|
WARNS?= 4 # XXX: const issues in sys_term.c
|
||||||
|
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
MAN= telnetd.8
|
||||||
|
|
||||||
|
PROG= telnetd
|
||||||
|
.if defined(__MINIX)
|
||||||
|
CPPFLAGS+=-DDIAGNOSTICS
|
||||||
|
.else # !defined(__MINIX)
|
||||||
|
CPPFLAGS+=-DLINEMODE -DKLUDGELINEMODE -DDIAGNOSTICS
|
||||||
|
.endif # !defined(__MINIX)
|
||||||
|
CPPFLAGS+=-DOLD_ENVIRON -DENV_HACK -DSECURELOGIN -DSUPPORT_UTMP -DSUPPORT_UTMPX
|
||||||
|
SRCS= authenc.c global.c slc.c state.c sys_term.c telnetd.c \
|
||||||
|
termstat.c utility.c
|
||||||
|
DPADD= ${LIBTELNETDIR}/libtelnet.a ${LIBTERMINFO} ${LIBUTIL}
|
||||||
|
LDADD+= ${LIBTELNETDIR}/libtelnet.a -lterminfo -lutil
|
||||||
|
|
||||||
|
CPPFLAGS+=-I${NETBSDSRCDIR}/lib
|
||||||
|
CPPFLAGS+=-I${.CURDIR}
|
||||||
|
|
||||||
|
LIBTELNETDIR!= cd ${.CURDIR}/../../lib/libtelnet; ${PRINTOBJDIR}
|
||||||
|
|
||||||
|
.if (${USE_KERBEROS} != "no")
|
||||||
|
CPPFLAGS+=-DKRB5 -DAUTHENTICATION -DENCRYPTION
|
||||||
|
LDADD+= -lkrb5 -lasn1 -lcom_err -lroken
|
||||||
|
DPADD+= ${LIBKRB5} ${LIBASN1} ${LIBCOM_ERR} ${LIBROKEN}
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.if (${MKCRYPTO} != "no")
|
||||||
|
LDADD+=-ldes -lcrypto -lcrypt
|
||||||
|
DPADD+=${LIBDES} ${LIBCRYPTO} ${LIBCRYPT}
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.if (${USE_PAM} != "no")
|
||||||
|
LDADD+= -lpam ${PAM_STATIC_LDADD}
|
||||||
|
DPADD+= ${LIBPAM} ${PAM_STATIC_DPADD}
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
||||||
85
libexec/telnetd/authenc.c
Normal file
85
libexec/telnetd/authenc.c
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
/* $NetBSD: authenc.c,v 1.12 2005/02/06 05:58:20 perry Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1991, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)authenc.c 8.2 (Berkeley) 5/30/95";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: authenc.c,v 1.12 2005/02/06 05:58:20 perry Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#if defined(AUTHENTICATION) || defined(ENCRYPTION)
|
||||||
|
#include "telnetd.h"
|
||||||
|
#include <libtelnet/misc.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
telnet_net_write(unsigned char *str, int len)
|
||||||
|
{
|
||||||
|
if (nfrontp + len < netobuf + BUFSIZ) {
|
||||||
|
output_datalen((const char *)str, len);
|
||||||
|
return(len);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
net_encrypt(void)
|
||||||
|
{
|
||||||
|
#ifdef ENCRYPTION
|
||||||
|
char *s = (nclearto > nbackp) ? nclearto : nbackp;
|
||||||
|
if (s < nfrontp && encrypt_output) {
|
||||||
|
(*encrypt_output)((unsigned char *)s, nfrontp - s);
|
||||||
|
}
|
||||||
|
nclearto = nfrontp;
|
||||||
|
#endif /* ENCRYPTION */
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
telnet_spin(void)
|
||||||
|
{
|
||||||
|
ttloop();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
telnet_getenv(char *val)
|
||||||
|
{
|
||||||
|
return(getenv(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
telnet_gets(char *prompt, char *result, int length, int echo)
|
||||||
|
{
|
||||||
|
return((char *)0);
|
||||||
|
}
|
||||||
|
#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
|
||||||
200
libexec/telnetd/defs.h
Normal file
200
libexec/telnetd/defs.h
Normal file
|
|
@ -0,0 +1,200 @@
|
||||||
|
/* $NetBSD: defs.h,v 1.16 2007/02/21 21:14:07 hubertf Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* from: @(#)defs.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Telnet server defines
|
||||||
|
*/
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#if defined(PRINTOPTIONS) && defined(DIAGNOSTICS)
|
||||||
|
#define TELOPTS
|
||||||
|
#define TELCMDS
|
||||||
|
#define SLC_NAMES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <arpa/telnet.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I/O data buffers defines
|
||||||
|
*/
|
||||||
|
#define NETSLOP 64
|
||||||
|
|
||||||
|
#define NIACCUM(c) do { \
|
||||||
|
*netip++ = c; \
|
||||||
|
ncc++; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* clock manipulations */
|
||||||
|
#define settimer(x) (clocks.x = ++clocks.system)
|
||||||
|
#define sequenceIs(x,y) (clocks.x < clocks.y)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Linemode support states, in decreasing order of importance
|
||||||
|
*/
|
||||||
|
#define REAL_LINEMODE 0x04
|
||||||
|
#define KLUDGE_OK 0x03
|
||||||
|
#define NO_AUTOKLUDGE 0x02
|
||||||
|
#define KLUDGE_LINEMODE 0x01
|
||||||
|
#define NO_LINEMODE 0x00
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structures of information for each special character function.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned char flag; /* the flags for this function */
|
||||||
|
cc_t val; /* the value of the special character */
|
||||||
|
} slcent, *Slcent;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
slcent defset; /* the default settings */
|
||||||
|
slcent current; /* the current settings */
|
||||||
|
cc_t *sptr; /* a pointer to the char in */
|
||||||
|
/* system data structures */
|
||||||
|
} slcfun, *Slcfun;
|
||||||
|
|
||||||
|
#ifdef DIAGNOSTICS
|
||||||
|
/*
|
||||||
|
* Diagnostics capabilities
|
||||||
|
*/
|
||||||
|
#define TD_REPORT 0x01 /* Report operations to client */
|
||||||
|
#define TD_EXERCISE 0x02 /* Exercise client's implementation */
|
||||||
|
#define TD_NETDATA 0x04 /* Display received data stream */
|
||||||
|
#define TD_PTYDATA 0x08 /* Display data passed to pty */
|
||||||
|
#define TD_OPTIONS 0x10 /* Report just telnet options */
|
||||||
|
#endif /* DIAGNOSTICS */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We keep track of each side of the option negotiation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MY_STATE_WILL 0x01
|
||||||
|
#define MY_WANT_STATE_WILL 0x02
|
||||||
|
#define MY_STATE_DO 0x04
|
||||||
|
#define MY_WANT_STATE_DO 0x08
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macros to check the current state of things
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define my_state_is_do(opt) (options[opt]&MY_STATE_DO)
|
||||||
|
#define my_state_is_will(opt) (options[opt]&MY_STATE_WILL)
|
||||||
|
#define my_want_state_is_do(opt) (options[opt]&MY_WANT_STATE_DO)
|
||||||
|
#define my_want_state_is_will(opt) (options[opt]&MY_WANT_STATE_WILL)
|
||||||
|
|
||||||
|
#define my_state_is_dont(opt) (!my_state_is_do(opt))
|
||||||
|
#define my_state_is_wont(opt) (!my_state_is_will(opt))
|
||||||
|
#define my_want_state_is_dont(opt) (!my_want_state_is_do(opt))
|
||||||
|
#define my_want_state_is_wont(opt) (!my_want_state_is_will(opt))
|
||||||
|
|
||||||
|
#define set_my_state_do(opt) (options[opt] |= MY_STATE_DO)
|
||||||
|
#define set_my_state_will(opt) (options[opt] |= MY_STATE_WILL)
|
||||||
|
#define set_my_want_state_do(opt) (options[opt] |= MY_WANT_STATE_DO)
|
||||||
|
#define set_my_want_state_will(opt) (options[opt] |= MY_WANT_STATE_WILL)
|
||||||
|
|
||||||
|
#define set_my_state_dont(opt) (options[opt] &= ~MY_STATE_DO)
|
||||||
|
#define set_my_state_wont(opt) (options[opt] &= ~MY_STATE_WILL)
|
||||||
|
#define set_my_want_state_dont(opt) (options[opt] &= ~MY_WANT_STATE_DO)
|
||||||
|
#define set_my_want_state_wont(opt) (options[opt] &= ~MY_WANT_STATE_WILL)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tricky code here. What we want to know is if the MY_STATE_WILL
|
||||||
|
* and MY_WANT_STATE_WILL bits have the same value. Since the two
|
||||||
|
* bits are adjacent, a little arithmetic will show that by adding
|
||||||
|
* in the lower bit, the upper bit will be set if the two bits were
|
||||||
|
* different, and clear if they were the same.
|
||||||
|
*/
|
||||||
|
#define my_will_wont_is_changing(opt) \
|
||||||
|
((options[opt]+MY_STATE_WILL) & MY_WANT_STATE_WILL)
|
||||||
|
|
||||||
|
#define my_do_dont_is_changing(opt) \
|
||||||
|
((options[opt]+MY_STATE_DO) & MY_WANT_STATE_DO)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make everything symmetrical
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define HIS_STATE_WILL MY_STATE_DO
|
||||||
|
#define HIS_WANT_STATE_WILL MY_WANT_STATE_DO
|
||||||
|
#define HIS_STATE_DO MY_STATE_WILL
|
||||||
|
#define HIS_WANT_STATE_DO MY_WANT_STATE_WILL
|
||||||
|
|
||||||
|
#define his_state_is_do my_state_is_will
|
||||||
|
#define his_state_is_will my_state_is_do
|
||||||
|
#define his_want_state_is_do my_want_state_is_will
|
||||||
|
#define his_want_state_is_will my_want_state_is_do
|
||||||
|
|
||||||
|
#define his_state_is_dont my_state_is_wont
|
||||||
|
#define his_state_is_wont my_state_is_dont
|
||||||
|
#define his_want_state_is_dont my_want_state_is_wont
|
||||||
|
#define his_want_state_is_wont my_want_state_is_dont
|
||||||
|
|
||||||
|
#define set_his_state_do set_my_state_will
|
||||||
|
#define set_his_state_will set_my_state_do
|
||||||
|
#define set_his_want_state_do set_my_want_state_will
|
||||||
|
#define set_his_want_state_will set_my_want_state_do
|
||||||
|
|
||||||
|
#define set_his_state_dont set_my_state_wont
|
||||||
|
#define set_his_state_wont set_my_state_dont
|
||||||
|
#define set_his_want_state_dont set_my_want_state_wont
|
||||||
|
#define set_his_want_state_wont set_my_want_state_dont
|
||||||
|
|
||||||
|
#define his_will_wont_is_changing my_do_dont_is_changing
|
||||||
|
#define his_do_dont_is_changing my_will_wont_is_changing
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialization buffer for tty device [16 characters long]
|
||||||
|
*/
|
||||||
|
#define NULL16STR "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
207
libexec/telnetd/ext.h
Normal file
207
libexec/telnetd/ext.h
Normal file
|
|
@ -0,0 +1,207 @@
|
||||||
|
/* $NetBSD: ext.h,v 1.22 2012/01/10 23:39:11 joerg Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* from: @(#)ext.h 8.2 (Berkeley) 12/15/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Telnet server variable declarations
|
||||||
|
*/
|
||||||
|
extern char options[256];
|
||||||
|
extern char do_dont_resp[256];
|
||||||
|
extern char will_wont_resp[256];
|
||||||
|
extern int linemode; /* linemode on/off */
|
||||||
|
#ifdef LINEMODE
|
||||||
|
extern int uselinemode; /* what linemode to use (on/off) */
|
||||||
|
extern int editmode; /* edit modes in use */
|
||||||
|
extern int useeditmode; /* edit modes to use */
|
||||||
|
extern int alwayslinemode; /* command line option */
|
||||||
|
# ifdef KLUDGELINEMODE
|
||||||
|
extern int lmodetype; /* Client support for linemode */
|
||||||
|
# endif /* KLUDGELINEMODE */
|
||||||
|
#endif /* LINEMODE */
|
||||||
|
extern int flowmode; /* current flow control state */
|
||||||
|
extern int restartany; /* restart output on any character state */
|
||||||
|
#ifdef DIAGNOSTICS
|
||||||
|
extern int diagnostic; /* telnet diagnostic capabilities */
|
||||||
|
#endif /* DIAGNOSTICS */
|
||||||
|
#ifdef SECURELOGIN
|
||||||
|
extern int require_secure_login;
|
||||||
|
#endif
|
||||||
|
#ifdef AUTHENTICATION
|
||||||
|
extern int auth_level;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern slcfun slctab[NSLC + 1]; /* slc mapping table */
|
||||||
|
extern char terminaltype[41];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I/O data buffers, pointers, and counters.
|
||||||
|
*/
|
||||||
|
extern char ptyobuf[BUFSIZ+NETSLOP], *pfrontp, *pbackp;
|
||||||
|
extern char netibuf[BUFSIZ], *netip;
|
||||||
|
extern char netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp;
|
||||||
|
extern char *neturg; /* one past last bye of urgent data */
|
||||||
|
extern int pcc, ncc;
|
||||||
|
extern int pty, net;
|
||||||
|
extern char *line;
|
||||||
|
extern int SYNCHing; /* we are in TELNET SYNCH mode */
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
extern void
|
||||||
|
_termstat(void),
|
||||||
|
add_slc(char, char, cc_t),
|
||||||
|
check_slc(void),
|
||||||
|
change_slc(int, int, cc_t),
|
||||||
|
cleanup(int) __dead,
|
||||||
|
clientstat(int, int, int),
|
||||||
|
copy_termbuf(char *, int),
|
||||||
|
deferslc(void),
|
||||||
|
defer_terminit(void),
|
||||||
|
do_opt_slc(unsigned char *, int),
|
||||||
|
doeof(void),
|
||||||
|
dooption(int),
|
||||||
|
dontoption(int),
|
||||||
|
edithost(const char *, const char *),
|
||||||
|
fatal(int, const char *) __dead,
|
||||||
|
fatalperror(int, const char *) __dead,
|
||||||
|
get_slc_defaults(void),
|
||||||
|
init_env(void),
|
||||||
|
init_termbuf(void),
|
||||||
|
interrupt(void),
|
||||||
|
localstat(void),
|
||||||
|
flowstat(void),
|
||||||
|
netclear(void),
|
||||||
|
netflush(void),
|
||||||
|
#ifdef DIAGNOSTICS
|
||||||
|
printoption(const char *, int),
|
||||||
|
printdata(const char *, char *, int),
|
||||||
|
#ifndef ENCRYPTION
|
||||||
|
printsub(int, unsigned char *, int),
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
ptyflush(void),
|
||||||
|
putchr(int),
|
||||||
|
recv_ayt(void),
|
||||||
|
send_do(int, int),
|
||||||
|
send_dont(int, int),
|
||||||
|
send_slc(void),
|
||||||
|
send_status(void),
|
||||||
|
send_will(int, int),
|
||||||
|
send_wont(int, int),
|
||||||
|
sendbrk(void),
|
||||||
|
sendsusp(void),
|
||||||
|
set_termbuf(void),
|
||||||
|
start_login(char *, int, char *) __dead,
|
||||||
|
start_slc(int),
|
||||||
|
startslave(char *, int, char *),
|
||||||
|
suboption(void),
|
||||||
|
telrcv(void),
|
||||||
|
ttloop(void),
|
||||||
|
tty_binaryin(int),
|
||||||
|
tty_binaryout(int);
|
||||||
|
|
||||||
|
extern char *
|
||||||
|
putf(const char *, char *);
|
||||||
|
|
||||||
|
extern int
|
||||||
|
end_slc(unsigned char **),
|
||||||
|
getnpty(void),
|
||||||
|
getpty(int *),
|
||||||
|
spcset(int, cc_t *, cc_t **),
|
||||||
|
stilloob(int),
|
||||||
|
terminit(void),
|
||||||
|
termstat(void),
|
||||||
|
tty_flowmode(void),
|
||||||
|
tty_restartany(void),
|
||||||
|
tty_isbinaryin(void),
|
||||||
|
tty_isbinaryout(void),
|
||||||
|
tty_iscrnl(void),
|
||||||
|
tty_isecho(void),
|
||||||
|
tty_isediting(void),
|
||||||
|
tty_islitecho(void),
|
||||||
|
tty_isnewmap(void),
|
||||||
|
tty_israw(void),
|
||||||
|
tty_issofttab(void),
|
||||||
|
tty_istrapsig(void),
|
||||||
|
tty_linemode(void);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
tty_rspeed(int),
|
||||||
|
tty_setecho(int),
|
||||||
|
tty_setedit(int),
|
||||||
|
tty_setlinemode(int),
|
||||||
|
tty_setlitecho(int),
|
||||||
|
tty_setsig(int),
|
||||||
|
tty_setsofttab(int),
|
||||||
|
tty_tspeed(int),
|
||||||
|
willoption(int),
|
||||||
|
wontoption(int),
|
||||||
|
writenet(unsigned char *, int);
|
||||||
|
|
||||||
|
extern int output_data(const char *, ...)
|
||||||
|
__attribute__((__format__(__printf__, 1, 2)));
|
||||||
|
extern int output_datalen(const char *, size_t);
|
||||||
|
|
||||||
|
#ifdef ENCRYPTION
|
||||||
|
extern char *nclearto;
|
||||||
|
#endif /* ENCRYPTION */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following are some clocks used to decide how to interpret
|
||||||
|
* the relationship between various variables.
|
||||||
|
*/
|
||||||
|
extern struct {
|
||||||
|
int
|
||||||
|
system, /* what the current time is */
|
||||||
|
echotoggle, /* last time user entered echo character */
|
||||||
|
modenegotiated, /* last time operating mode negotiated */
|
||||||
|
didnetreceive, /* last time we read data from network */
|
||||||
|
ttypesubopt, /* ttype subopt is received */
|
||||||
|
tspeedsubopt, /* tspeed subopt is received */
|
||||||
|
environsubopt, /* environ subopt is received */
|
||||||
|
oenvironsubopt, /* old environ subopt is received */
|
||||||
|
xdisplocsubopt, /* xdisploc subopt is received */
|
||||||
|
baseline, /* time started to do timed action */
|
||||||
|
gotDM; /* when did we last see a data mark */
|
||||||
|
} clocks;
|
||||||
|
|
||||||
|
#ifndef DEFAULT_IM
|
||||||
|
# define DEFAULT_IM "\r\n\r\n4.4 BSD UNIX (%h) (%t)\r\n\r\r\n\r"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef AUTHENTICATION
|
||||||
|
#include <libtelnet/auth.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENCRYPTION
|
||||||
|
#include <libtelnet/encrypt.h>
|
||||||
|
#endif
|
||||||
51
libexec/telnetd/global.c
Normal file
51
libexec/telnetd/global.c
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* $NetBSD: global.c,v 1.8 2003/08/07 09:46:51 agc Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)global.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: global.c,v 1.8 2003/08/07 09:46:51 agc Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate global variables. We do this
|
||||||
|
* by including the header file that defines
|
||||||
|
* them all as externs, but first we define
|
||||||
|
* the keyword "extern" to be nothing, so that
|
||||||
|
* we will actually allocate the space.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <defs.h>
|
||||||
|
#define extern
|
||||||
|
#include <ext.h>
|
||||||
38
libexec/telnetd/pathnames.h
Normal file
38
libexec/telnetd/pathnames.h
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* $NetBSD: pathnames.h,v 1.7 2003/08/07 09:46:51 agc Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* from: @(#)pathnames.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <paths.h>
|
||||||
|
|
||||||
|
#ifndef _PATH_LOGIN
|
||||||
|
# define _PATH_LOGIN "/usr/bin/login"
|
||||||
|
#endif
|
||||||
488
libexec/telnetd/slc.c
Normal file
488
libexec/telnetd/slc.c
Normal file
|
|
@ -0,0 +1,488 @@
|
||||||
|
/* $NetBSD: slc.c,v 1.15 2006/11/24 19:46:58 christos Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)slc.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: slc.c,v 1.15 2006/11/24 19:46:58 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#include "telnetd.h"
|
||||||
|
|
||||||
|
#ifdef LINEMODE
|
||||||
|
/*
|
||||||
|
* local varibles
|
||||||
|
*/
|
||||||
|
static unsigned char *def_slcbuf = (unsigned char *)0;
|
||||||
|
static int def_slclen = 0;
|
||||||
|
static int slcchange; /* change to slc is requested */
|
||||||
|
static unsigned char *slcptr; /* pointer into slc buffer */
|
||||||
|
static unsigned char slcbuf[NSLC*6]; /* buffer for slc negotiation */
|
||||||
|
|
||||||
|
void default_slc(void);
|
||||||
|
void process_slc(u_int, u_int, cc_t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* send_slc
|
||||||
|
*
|
||||||
|
* Write out the current special characters to the client.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
send_slc(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send out list of triplets of special characters
|
||||||
|
* to client. We only send info on the characters
|
||||||
|
* that are currently supported.
|
||||||
|
*/
|
||||||
|
for (i = 1; i <= NSLC; i++) {
|
||||||
|
if ((slctab[i].defset.flag & SLC_LEVELBITS) == SLC_NOSUPPORT)
|
||||||
|
continue;
|
||||||
|
add_slc((unsigned char)i, slctab[i].current.flag,
|
||||||
|
slctab[i].current.val);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* end of send_slc */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* default_slc
|
||||||
|
*
|
||||||
|
* Set pty special characters to all the defaults.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
default_slc(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i <= NSLC; i++) {
|
||||||
|
slctab[i].current.val = slctab[i].defset.val;
|
||||||
|
if (slctab[i].current.val == (cc_t)(_POSIX_VDISABLE))
|
||||||
|
slctab[i].current.flag = SLC_NOSUPPORT;
|
||||||
|
else
|
||||||
|
slctab[i].current.flag = slctab[i].defset.flag;
|
||||||
|
if (slctab[i].sptr) {
|
||||||
|
*(slctab[i].sptr) = slctab[i].defset.val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slcchange = 1;
|
||||||
|
|
||||||
|
} /* end of default_slc */
|
||||||
|
#endif /* LINEMODE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_slc_defaults
|
||||||
|
*
|
||||||
|
* Initialize the slc mapping table.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
get_slc_defaults(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
init_termbuf();
|
||||||
|
|
||||||
|
for (i = 1; i <= NSLC; i++) {
|
||||||
|
slctab[i].defset.flag =
|
||||||
|
spcset(i, &slctab[i].defset.val, &slctab[i].sptr);
|
||||||
|
slctab[i].current.flag = SLC_NOSUPPORT;
|
||||||
|
slctab[i].current.val = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* end of get_slc_defaults */
|
||||||
|
|
||||||
|
#ifdef LINEMODE
|
||||||
|
/*
|
||||||
|
* add_slc
|
||||||
|
*
|
||||||
|
* Add an slc triplet to the slc buffer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
add_slc(char func, char flag, cc_t val)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((*slcptr++ = (unsigned char)func) == 0xff)
|
||||||
|
*slcptr++ = 0xff;
|
||||||
|
|
||||||
|
if ((*slcptr++ = (unsigned char)flag) == 0xff)
|
||||||
|
*slcptr++ = 0xff;
|
||||||
|
|
||||||
|
if ((*slcptr++ = (unsigned char)val) == 0xff)
|
||||||
|
*slcptr++ = 0xff;
|
||||||
|
|
||||||
|
} /* end of add_slc */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* start_slc
|
||||||
|
*
|
||||||
|
* Get ready to process incoming slc's and respond to them.
|
||||||
|
*
|
||||||
|
* The parameter getit is non-zero if it is necessary to grab a copy
|
||||||
|
* of the terminal control structures.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
start_slc(int getit)
|
||||||
|
{
|
||||||
|
|
||||||
|
slcchange = 0;
|
||||||
|
if (getit)
|
||||||
|
init_termbuf();
|
||||||
|
(void)snprintf((char *)slcbuf, sizeof slcbuf, "%c%c%c%c",
|
||||||
|
IAC, SB, TELOPT_LINEMODE, LM_SLC);
|
||||||
|
slcptr = slcbuf + 4;
|
||||||
|
|
||||||
|
} /* end of start_slc */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* end_slc
|
||||||
|
*
|
||||||
|
* Finish up the slc negotiation. If something to send, then send it.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
end_slc(unsigned char **bufp)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a change has occurred, store the new terminal control
|
||||||
|
* structures back to the terminal driver.
|
||||||
|
*/
|
||||||
|
if (slcchange) {
|
||||||
|
set_termbuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the pty state has not yet been fully processed and there is a
|
||||||
|
* deferred slc request from the client, then do not send any
|
||||||
|
* sort of slc negotiation now. We will respond to the client's
|
||||||
|
* request very soon.
|
||||||
|
*/
|
||||||
|
if (def_slcbuf && (terminit() == 0)) {
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slcptr > (slcbuf + 4)) {
|
||||||
|
if (bufp) {
|
||||||
|
*bufp = &slcbuf[4];
|
||||||
|
return(slcptr - slcbuf - 4);
|
||||||
|
} else {
|
||||||
|
(void) snprintf((char *)slcptr,
|
||||||
|
sizeof(slcbuf) - (slcptr - slcbuf), "%c%c",
|
||||||
|
IAC, SE);
|
||||||
|
slcptr += 2;
|
||||||
|
len = slcptr - slcbuf;
|
||||||
|
writenet(slcbuf, len);
|
||||||
|
netflush(); /* force it out immediately */
|
||||||
|
DIAG(TD_OPTIONS, printsub('>', slcbuf+2, len-2););
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
} /* end of end_slc */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* process_slc
|
||||||
|
*
|
||||||
|
* Figure out what to do about the client's slc
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
process_slc(u_int func, u_int flag, cc_t val)
|
||||||
|
{
|
||||||
|
int hislevel, mylevel, ack;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure that we know something about this function
|
||||||
|
*/
|
||||||
|
if (func > NSLC) {
|
||||||
|
add_slc(func, SLC_NOSUPPORT, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process the special case requests of 0 SLC_DEFAULT 0
|
||||||
|
* and 0 SLC_VARIABLE 0. Be a little forgiving here, don't
|
||||||
|
* worry about whether the value is actually 0 or not.
|
||||||
|
*/
|
||||||
|
if (func == 0) {
|
||||||
|
if ((flag = flag & SLC_LEVELBITS) == SLC_DEFAULT) {
|
||||||
|
default_slc();
|
||||||
|
send_slc();
|
||||||
|
} else if (flag == SLC_VARIABLE) {
|
||||||
|
send_slc();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Appears to be a function that we know something about. So
|
||||||
|
* get on with it and see what we know.
|
||||||
|
*/
|
||||||
|
|
||||||
|
hislevel = flag & SLC_LEVELBITS;
|
||||||
|
mylevel = slctab[func].current.flag & SLC_LEVELBITS;
|
||||||
|
ack = flag & SLC_ACK;
|
||||||
|
/*
|
||||||
|
* ignore the command if:
|
||||||
|
* the function value and level are the same as what we already have;
|
||||||
|
* or the level is the same and the ack bit is set
|
||||||
|
*/
|
||||||
|
if (hislevel == mylevel && (val == slctab[func].current.val || ack)) {
|
||||||
|
return;
|
||||||
|
} else if (ack) {
|
||||||
|
/*
|
||||||
|
* If we get here, we got an ack, but the levels don't match.
|
||||||
|
* This shouldn't happen. If it does, it is probably because
|
||||||
|
* we have sent two requests to set a variable without getting
|
||||||
|
* a response between them, and this is the first response.
|
||||||
|
* So, ignore it, and wait for the next response.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
change_slc(func, flag, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* end of process_slc */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* change_slc
|
||||||
|
*
|
||||||
|
* Process a request to change one of our special characters.
|
||||||
|
* Compare client's request with what we are capable of supporting.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
change_slc(int func, int flag, cc_t val)
|
||||||
|
{
|
||||||
|
int hislevel, mylevel;
|
||||||
|
|
||||||
|
hislevel = flag & SLC_LEVELBITS;
|
||||||
|
mylevel = slctab[func].defset.flag & SLC_LEVELBITS;
|
||||||
|
/*
|
||||||
|
* If client is setting a function to NOSUPPORT
|
||||||
|
* or DEFAULT, then we can easily and directly
|
||||||
|
* accommodate the request.
|
||||||
|
*/
|
||||||
|
if (hislevel == SLC_NOSUPPORT) {
|
||||||
|
slctab[func].current.flag = flag;
|
||||||
|
slctab[func].current.val = (cc_t)_POSIX_VDISABLE;
|
||||||
|
flag |= SLC_ACK;
|
||||||
|
add_slc(func, flag, val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (hislevel == SLC_DEFAULT) {
|
||||||
|
/*
|
||||||
|
* Special case here. If client tells us to use
|
||||||
|
* the default on a function we don't support, then
|
||||||
|
* return NOSUPPORT instead of what we may have as a
|
||||||
|
* default level of DEFAULT.
|
||||||
|
*/
|
||||||
|
if (mylevel == SLC_DEFAULT) {
|
||||||
|
slctab[func].current.flag = SLC_NOSUPPORT;
|
||||||
|
} else {
|
||||||
|
slctab[func].current.flag = slctab[func].defset.flag;
|
||||||
|
}
|
||||||
|
slctab[func].current.val = slctab[func].defset.val;
|
||||||
|
add_slc(func, slctab[func].current.flag,
|
||||||
|
slctab[func].current.val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Client wants us to change to a new value or he
|
||||||
|
* is telling us that he can't change to our value.
|
||||||
|
* Some of the slc's we support and can change,
|
||||||
|
* some we do support but can't change,
|
||||||
|
* and others we don't support at all.
|
||||||
|
* If we can change it then we have a pointer to
|
||||||
|
* the place to put the new value, so change it,
|
||||||
|
* otherwise, continue the negotiation.
|
||||||
|
*/
|
||||||
|
if (slctab[func].sptr) {
|
||||||
|
/*
|
||||||
|
* We can change this one.
|
||||||
|
*/
|
||||||
|
slctab[func].current.val = val;
|
||||||
|
*(slctab[func].sptr) = val;
|
||||||
|
slctab[func].current.flag = flag;
|
||||||
|
flag |= SLC_ACK;
|
||||||
|
slcchange = 1;
|
||||||
|
add_slc(func, flag, val);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* It is not possible for us to support this
|
||||||
|
* request as he asks.
|
||||||
|
*
|
||||||
|
* If our level is DEFAULT, then just ack whatever was
|
||||||
|
* sent.
|
||||||
|
*
|
||||||
|
* If he can't change and we can't change,
|
||||||
|
* then degenerate to NOSUPPORT.
|
||||||
|
*
|
||||||
|
* Otherwise we send our level back to him, (CANTCHANGE
|
||||||
|
* or NOSUPPORT) and if CANTCHANGE, send
|
||||||
|
* our value as well.
|
||||||
|
*/
|
||||||
|
if (mylevel == SLC_DEFAULT) {
|
||||||
|
slctab[func].current.flag = flag;
|
||||||
|
slctab[func].current.val = val;
|
||||||
|
flag |= SLC_ACK;
|
||||||
|
} else if (hislevel == SLC_CANTCHANGE &&
|
||||||
|
mylevel == SLC_CANTCHANGE) {
|
||||||
|
flag &= ~SLC_LEVELBITS;
|
||||||
|
flag |= SLC_NOSUPPORT;
|
||||||
|
slctab[func].current.flag = flag;
|
||||||
|
} else {
|
||||||
|
flag &= ~SLC_LEVELBITS;
|
||||||
|
flag |= mylevel;
|
||||||
|
slctab[func].current.flag = flag;
|
||||||
|
if (mylevel == SLC_CANTCHANGE) {
|
||||||
|
slctab[func].current.val =
|
||||||
|
slctab[func].defset.val;
|
||||||
|
val = slctab[func].current.val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add_slc(func, flag, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* end of change_slc */
|
||||||
|
|
||||||
|
#if VEOF == VMIN
|
||||||
|
cc_t oldeofc = '\004';
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check_slc
|
||||||
|
*
|
||||||
|
* Check the special characters in use and notify the client if any have
|
||||||
|
* changed. Only those characters that are capable of being changed are
|
||||||
|
* likely to have changed. If a local change occurs, kick the support level
|
||||||
|
* and flags up to the defaults.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
check_slc(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i <= NSLC; i++) {
|
||||||
|
#if VEOF == VMIN
|
||||||
|
/*
|
||||||
|
* In a perfect world this would be a neat little
|
||||||
|
* function. But in this world, we should not notify
|
||||||
|
* client of changes to the VEOF char when
|
||||||
|
* ICANON is off, because it is not representing
|
||||||
|
* a special character.
|
||||||
|
*/
|
||||||
|
if (i == SLC_EOF) {
|
||||||
|
if (!tty_isediting())
|
||||||
|
continue;
|
||||||
|
else if (slctab[i].sptr)
|
||||||
|
oldeofc = *(slctab[i].sptr);
|
||||||
|
}
|
||||||
|
#endif /* VEOF == VMIN */
|
||||||
|
if (slctab[i].sptr &&
|
||||||
|
(*(slctab[i].sptr) != slctab[i].current.val)) {
|
||||||
|
slctab[i].current.val = *(slctab[i].sptr);
|
||||||
|
if (*(slctab[i].sptr) == (cc_t)_POSIX_VDISABLE)
|
||||||
|
slctab[i].current.flag = SLC_NOSUPPORT;
|
||||||
|
else
|
||||||
|
slctab[i].current.flag = slctab[i].defset.flag;
|
||||||
|
add_slc((unsigned char)i, slctab[i].current.flag,
|
||||||
|
slctab[i].current.val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /* check_slc */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_opt_slc
|
||||||
|
*
|
||||||
|
* Process an slc option buffer. Defer processing of incoming slc's
|
||||||
|
* until after the terminal state has been processed. Save the first slc
|
||||||
|
* request that comes along, but discard all others.
|
||||||
|
*
|
||||||
|
* ptr points to the beginning of the buffer, len is the length.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
do_opt_slc(unsigned char *ptr, int len)
|
||||||
|
{
|
||||||
|
unsigned char func, flag;
|
||||||
|
cc_t val;
|
||||||
|
unsigned char *end = ptr + len;
|
||||||
|
|
||||||
|
if (terminit()) { /* go ahead */
|
||||||
|
while (ptr < end) {
|
||||||
|
func = *ptr++;
|
||||||
|
if (ptr >= end) break;
|
||||||
|
flag = *ptr++;
|
||||||
|
if (ptr >= end) break;
|
||||||
|
val = (cc_t)*ptr++;
|
||||||
|
|
||||||
|
process_slc((u_int)func, (u_int)flag, val);
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* save this slc buffer if it is the first, otherwise dump
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
if (def_slcbuf == (unsigned char *)0) {
|
||||||
|
def_slclen = len;
|
||||||
|
def_slcbuf = (unsigned char *)malloc((unsigned)len);
|
||||||
|
if (def_slcbuf == (unsigned char *)0)
|
||||||
|
return; /* too bad */
|
||||||
|
memcpy(def_slcbuf, ptr, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* end of do_opt_slc */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* deferslc
|
||||||
|
*
|
||||||
|
* Do slc stuff that was deferred.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
deferslc(void)
|
||||||
|
{
|
||||||
|
if (def_slcbuf) {
|
||||||
|
start_slc(1);
|
||||||
|
do_opt_slc(def_slcbuf, def_slclen);
|
||||||
|
(void) end_slc(0);
|
||||||
|
free(def_slcbuf);
|
||||||
|
def_slcbuf = (unsigned char *)0;
|
||||||
|
def_slclen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* end of deferslc */
|
||||||
|
|
||||||
|
#endif /* LINEMODE */
|
||||||
1680
libexec/telnetd/state.c
Normal file
1680
libexec/telnetd/state.c
Normal file
File diff suppressed because it is too large
Load Diff
798
libexec/telnetd/sys_term.c
Normal file
798
libexec/telnetd/sys_term.c
Normal file
|
|
@ -0,0 +1,798 @@
|
||||||
|
/* $NetBSD: sys_term.c,v 1.47 2013/06/28 15:48:02 christos Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)sys_term.c 8.4+1 (Berkeley) 5/30/95";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: sys_term.c,v 1.47 2013/06/28 15:48:02 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#include "telnetd.h"
|
||||||
|
#include "pathnames.h"
|
||||||
|
|
||||||
|
#include <util.h>
|
||||||
|
#include <vis.h>
|
||||||
|
|
||||||
|
#ifdef SUPPORT_UTMP
|
||||||
|
#include <utmp.h>
|
||||||
|
#endif
|
||||||
|
#ifdef SUPPORT_UTMPX
|
||||||
|
#include <utmpx.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SCPYN(a, b) (void) strncpy(a, b, sizeof(a))
|
||||||
|
#define SCMPN(a, b) strncmp(a, b, sizeof(a))
|
||||||
|
|
||||||
|
struct termios termbuf, termbuf2; /* pty control structure */
|
||||||
|
|
||||||
|
void getptyslave(void);
|
||||||
|
int cleanopen(char *);
|
||||||
|
char **addarg(char **, const char *);
|
||||||
|
void scrub_env(void);
|
||||||
|
int getent(char *, char *);
|
||||||
|
char *getstr(const char *, char **);
|
||||||
|
#ifdef KRB5
|
||||||
|
extern void kerberos5_cleanup(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_termbuf()
|
||||||
|
* copy_termbuf(cp)
|
||||||
|
* set_termbuf()
|
||||||
|
*
|
||||||
|
* These three routines are used to get and set the "termbuf" structure
|
||||||
|
* to and from the kernel. init_termbuf() gets the current settings.
|
||||||
|
* copy_termbuf() hands in a new "termbuf" to write to the kernel, and
|
||||||
|
* set_termbuf() writes the structure into the kernel.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
init_termbuf(void)
|
||||||
|
{
|
||||||
|
(void) tcgetattr(pty, &termbuf);
|
||||||
|
termbuf2 = termbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(LINEMODE) && defined(TIOCPKT_IOCTL)
|
||||||
|
void
|
||||||
|
copy_termbuf(char *cp, int len)
|
||||||
|
{
|
||||||
|
if ((size_t)len > sizeof(termbuf))
|
||||||
|
len = sizeof(termbuf);
|
||||||
|
memmove((char *)&termbuf, cp, len);
|
||||||
|
termbuf2 = termbuf;
|
||||||
|
}
|
||||||
|
#endif /* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */
|
||||||
|
|
||||||
|
void
|
||||||
|
set_termbuf(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Only make the necessary changes.
|
||||||
|
*/
|
||||||
|
if (memcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf)))
|
||||||
|
(void) tcsetattr(pty, TCSANOW, &termbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* spcset(func, valp, valpp)
|
||||||
|
*
|
||||||
|
* This function takes various special characters (func), and
|
||||||
|
* sets *valp to the current value of that character, and
|
||||||
|
* *valpp to point to where in the "termbuf" structure that
|
||||||
|
* value is kept.
|
||||||
|
*
|
||||||
|
* It returns the SLC_ level of support for this function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
spcset(int func, cc_t *valp, cc_t **valpp)
|
||||||
|
{
|
||||||
|
|
||||||
|
#define setval(a, b) *valp = termbuf.c_cc[a]; \
|
||||||
|
*valpp = &termbuf.c_cc[a]; \
|
||||||
|
return(b);
|
||||||
|
#define defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT);
|
||||||
|
|
||||||
|
switch(func) {
|
||||||
|
case SLC_EOF:
|
||||||
|
setval(VEOF, SLC_VARIABLE);
|
||||||
|
case SLC_EC:
|
||||||
|
setval(VERASE, SLC_VARIABLE);
|
||||||
|
case SLC_EL:
|
||||||
|
setval(VKILL, SLC_VARIABLE);
|
||||||
|
case SLC_IP:
|
||||||
|
setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
|
||||||
|
case SLC_ABORT:
|
||||||
|
setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
|
||||||
|
case SLC_XON:
|
||||||
|
setval(VSTART, SLC_VARIABLE);
|
||||||
|
case SLC_XOFF:
|
||||||
|
setval(VSTOP, SLC_VARIABLE);
|
||||||
|
case SLC_EW:
|
||||||
|
setval(VWERASE, SLC_VARIABLE);
|
||||||
|
case SLC_RP:
|
||||||
|
setval(VREPRINT, SLC_VARIABLE);
|
||||||
|
case SLC_LNEXT:
|
||||||
|
setval(VLNEXT, SLC_VARIABLE);
|
||||||
|
case SLC_AO:
|
||||||
|
setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);
|
||||||
|
case SLC_SUSP:
|
||||||
|
setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN);
|
||||||
|
case SLC_FORW1:
|
||||||
|
setval(VEOL, SLC_VARIABLE);
|
||||||
|
case SLC_FORW2:
|
||||||
|
setval(VEOL2, SLC_VARIABLE);
|
||||||
|
case SLC_AYT:
|
||||||
|
setval(VSTATUS, SLC_VARIABLE);
|
||||||
|
|
||||||
|
case SLC_BRK:
|
||||||
|
case SLC_SYNCH:
|
||||||
|
case SLC_EOR:
|
||||||
|
defval(0);
|
||||||
|
|
||||||
|
default:
|
||||||
|
*valp = 0;
|
||||||
|
*valpp = 0;
|
||||||
|
return(SLC_NOSUPPORT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getpty()
|
||||||
|
*
|
||||||
|
* Allocate a pty. As a side effect, the external character
|
||||||
|
* array "line" contains the name of the slave side.
|
||||||
|
*
|
||||||
|
* Returns the file descriptor of the opened pty.
|
||||||
|
*/
|
||||||
|
#ifndef __GNUC__
|
||||||
|
char *line = NULL16STR;
|
||||||
|
#else
|
||||||
|
static char Xline[] = NULL16STR;
|
||||||
|
char *line = Xline;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int ptyslavefd; /* for cleanopen() */
|
||||||
|
|
||||||
|
int
|
||||||
|
getpty(int *ptynum)
|
||||||
|
{
|
||||||
|
int ptyfd;
|
||||||
|
|
||||||
|
ptyfd = openpty(ptynum, &ptyslavefd, line, NULL, NULL);
|
||||||
|
if (ptyfd == 0)
|
||||||
|
return *ptynum;
|
||||||
|
ptyslavefd = -1;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef LINEMODE
|
||||||
|
/*
|
||||||
|
* tty_flowmode() Find out if flow control is enabled or disabled.
|
||||||
|
* tty_linemode() Find out if linemode (external processing) is enabled.
|
||||||
|
* tty_setlinemod(on) Turn on/off linemode.
|
||||||
|
* tty_isecho() Find out if echoing is turned on.
|
||||||
|
* tty_setecho(on) Enable/disable character echoing.
|
||||||
|
* tty_israw() Find out if terminal is in RAW mode.
|
||||||
|
* tty_binaryin(on) Turn on/off BINARY on input.
|
||||||
|
* tty_binaryout(on) Turn on/off BINARY on output.
|
||||||
|
* tty_isediting() Find out if line editing is enabled.
|
||||||
|
* tty_istrapsig() Find out if signal trapping is enabled.
|
||||||
|
* tty_setedit(on) Turn on/off line editing.
|
||||||
|
* tty_setsig(on) Turn on/off signal trapping.
|
||||||
|
* tty_issofttab() Find out if tab expansion is enabled.
|
||||||
|
* tty_setsofttab(on) Turn on/off soft tab expansion.
|
||||||
|
* tty_islitecho() Find out if typed control chars are echoed literally
|
||||||
|
* tty_setlitecho() Turn on/off literal echo of control chars
|
||||||
|
* tty_tspeed(val) Set transmit speed to val.
|
||||||
|
* tty_rspeed(val) Set receive speed to val.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_linemode(void)
|
||||||
|
{
|
||||||
|
return(termbuf.c_lflag & EXTPROC);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_setlinemode(int on)
|
||||||
|
{
|
||||||
|
set_termbuf();
|
||||||
|
(void) ioctl(pty, TIOCEXT, (char *)&on);
|
||||||
|
init_termbuf();
|
||||||
|
}
|
||||||
|
#endif /* LINEMODE */
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_isecho(void)
|
||||||
|
{
|
||||||
|
return (termbuf.c_lflag & ECHO);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_flowmode(void)
|
||||||
|
{
|
||||||
|
return((termbuf.c_iflag & IXON) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_restartany(void)
|
||||||
|
{
|
||||||
|
return((termbuf.c_iflag & IXANY) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_setecho(int on)
|
||||||
|
{
|
||||||
|
if (on)
|
||||||
|
termbuf.c_lflag |= ECHO;
|
||||||
|
else
|
||||||
|
termbuf.c_lflag &= ~ECHO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_israw(void)
|
||||||
|
{
|
||||||
|
return(!(termbuf.c_lflag & ICANON));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_binaryin(int on)
|
||||||
|
{
|
||||||
|
if (on) {
|
||||||
|
termbuf.c_iflag &= ~ISTRIP;
|
||||||
|
} else {
|
||||||
|
termbuf.c_iflag |= ISTRIP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_binaryout(int on)
|
||||||
|
{
|
||||||
|
if (on) {
|
||||||
|
termbuf.c_cflag &= ~(CSIZE|PARENB);
|
||||||
|
termbuf.c_cflag |= CS8;
|
||||||
|
termbuf.c_oflag &= ~OPOST;
|
||||||
|
} else {
|
||||||
|
termbuf.c_cflag &= ~CSIZE;
|
||||||
|
termbuf.c_cflag |= CS7|PARENB;
|
||||||
|
termbuf.c_oflag |= OPOST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_isbinaryin(void)
|
||||||
|
{
|
||||||
|
return(!(termbuf.c_iflag & ISTRIP));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_isbinaryout(void)
|
||||||
|
{
|
||||||
|
return(!(termbuf.c_oflag&OPOST));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef LINEMODE
|
||||||
|
int
|
||||||
|
tty_isediting(void)
|
||||||
|
{
|
||||||
|
return(termbuf.c_lflag & ICANON);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_istrapsig(void)
|
||||||
|
{
|
||||||
|
return(termbuf.c_lflag & ISIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_setedit(int on)
|
||||||
|
{
|
||||||
|
if (on)
|
||||||
|
termbuf.c_lflag |= ICANON;
|
||||||
|
else
|
||||||
|
termbuf.c_lflag &= ~ICANON;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_setsig(int on)
|
||||||
|
{
|
||||||
|
if (on)
|
||||||
|
termbuf.c_lflag |= ISIG;
|
||||||
|
else
|
||||||
|
termbuf.c_lflag &= ~ISIG;
|
||||||
|
}
|
||||||
|
#endif /* LINEMODE */
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_issofttab(void)
|
||||||
|
{
|
||||||
|
# ifdef OXTABS
|
||||||
|
return (termbuf.c_oflag & OXTABS);
|
||||||
|
# endif
|
||||||
|
# ifdef TABDLY
|
||||||
|
return ((termbuf.c_oflag & TABDLY) == TAB3);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_setsofttab(int on)
|
||||||
|
{
|
||||||
|
if (on) {
|
||||||
|
# ifdef OXTABS
|
||||||
|
termbuf.c_oflag |= OXTABS;
|
||||||
|
# endif
|
||||||
|
# ifdef TABDLY
|
||||||
|
termbuf.c_oflag &= ~TABDLY;
|
||||||
|
termbuf.c_oflag |= TAB3;
|
||||||
|
# endif
|
||||||
|
} else {
|
||||||
|
# ifdef OXTABS
|
||||||
|
termbuf.c_oflag &= ~OXTABS;
|
||||||
|
# endif
|
||||||
|
# ifdef TABDLY
|
||||||
|
termbuf.c_oflag &= ~TABDLY;
|
||||||
|
termbuf.c_oflag |= TAB0;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_islitecho(void)
|
||||||
|
{
|
||||||
|
# ifdef ECHOCTL
|
||||||
|
return (!(termbuf.c_lflag & ECHOCTL));
|
||||||
|
# endif
|
||||||
|
# ifdef TCTLECH
|
||||||
|
return (!(termbuf.c_lflag & TCTLECH));
|
||||||
|
# endif
|
||||||
|
# if !defined(ECHOCTL) && !defined(TCTLECH)
|
||||||
|
return (0); /* assumes ctl chars are echoed '^x' */
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_setlitecho(int on)
|
||||||
|
{
|
||||||
|
# ifdef ECHOCTL
|
||||||
|
if (on)
|
||||||
|
termbuf.c_lflag &= ~ECHOCTL;
|
||||||
|
else
|
||||||
|
termbuf.c_lflag |= ECHOCTL;
|
||||||
|
# endif
|
||||||
|
# ifdef TCTLECH
|
||||||
|
if (on)
|
||||||
|
termbuf.c_lflag &= ~TCTLECH;
|
||||||
|
else
|
||||||
|
termbuf.c_lflag |= TCTLECH;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_iscrnl(void)
|
||||||
|
{
|
||||||
|
return (termbuf.c_iflag & ICRNL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_tspeed(int val)
|
||||||
|
{
|
||||||
|
cfsetospeed(&termbuf, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_rspeed(int val)
|
||||||
|
{
|
||||||
|
cfsetispeed(&termbuf, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getptyslave()
|
||||||
|
*
|
||||||
|
* Open the slave side of the pty, and do any initialization
|
||||||
|
* that is necessary. The return value is a file descriptor
|
||||||
|
* for the slave side.
|
||||||
|
*/
|
||||||
|
extern int def_tspeed, def_rspeed;
|
||||||
|
extern int def_row, def_col;
|
||||||
|
|
||||||
|
void
|
||||||
|
getptyslave(void)
|
||||||
|
{
|
||||||
|
int t = -1;
|
||||||
|
|
||||||
|
#ifdef LINEMODE
|
||||||
|
int waslm;
|
||||||
|
#endif
|
||||||
|
struct winsize ws;
|
||||||
|
/*
|
||||||
|
* Opening the slave side may cause initilization of the
|
||||||
|
* kernel tty structure. We need remember the state of
|
||||||
|
* if linemode was turned on
|
||||||
|
* terminal window size
|
||||||
|
* terminal speed
|
||||||
|
* so that we can re-set them if we need to.
|
||||||
|
*/
|
||||||
|
#ifdef LINEMODE
|
||||||
|
waslm = tty_linemode();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that we don't have a controlling tty, and
|
||||||
|
* that we are the session (process group) leader.
|
||||||
|
*/
|
||||||
|
t = open(_PATH_TTY, O_RDWR);
|
||||||
|
if (t >= 0) {
|
||||||
|
(void) ioctl(t, TIOCNOTTY, (char *)0);
|
||||||
|
(void) close(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
t = cleanopen(line);
|
||||||
|
if (t < 0)
|
||||||
|
fatalperror(net, line);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set up the tty modes as we like them to be.
|
||||||
|
*/
|
||||||
|
init_termbuf();
|
||||||
|
if (def_row || def_col) {
|
||||||
|
memset((char *)&ws, 0, sizeof(ws));
|
||||||
|
ws.ws_col = def_col;
|
||||||
|
ws.ws_row = def_row;
|
||||||
|
(void)ioctl(t, TIOCSWINSZ, (char *)&ws);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Settings for sgtty based systems
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Settings for all other termios/termio based
|
||||||
|
* systems, other than 4.4BSD. In 4.4BSD the
|
||||||
|
* kernel does the initial terminal setup.
|
||||||
|
*/
|
||||||
|
tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600);
|
||||||
|
tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600);
|
||||||
|
#ifdef LINEMODE
|
||||||
|
if (waslm)
|
||||||
|
tty_setlinemode(1);
|
||||||
|
#endif /* LINEMODE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the tty modes, and make this our controlling tty.
|
||||||
|
*/
|
||||||
|
set_termbuf();
|
||||||
|
if (login_tty(t) == -1)
|
||||||
|
fatalperror(net, "login_tty");
|
||||||
|
if (net > 2)
|
||||||
|
(void) close(net);
|
||||||
|
if (pty > 2) {
|
||||||
|
(void) close(pty);
|
||||||
|
pty = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the specified slave side of the pty,
|
||||||
|
* making sure that we have a clean tty.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
cleanopen(char *ttyline)
|
||||||
|
{
|
||||||
|
return ptyslavefd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* startslave(host)
|
||||||
|
*
|
||||||
|
* Given a hostname, do whatever
|
||||||
|
* is necessary to startup the login process on the slave side of the pty.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
void
|
||||||
|
startslave(char *host, int autologin, char *autoname)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#ifdef AUTHENTICATION
|
||||||
|
if (!autoname || !autoname[0])
|
||||||
|
autologin = 0;
|
||||||
|
|
||||||
|
if (autologin < auth_level) {
|
||||||
|
fatal(net, "Authorization failed");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
if ((i = fork()) < 0)
|
||||||
|
fatalperror(net, "fork");
|
||||||
|
if (i) {
|
||||||
|
} else {
|
||||||
|
getptyslave();
|
||||||
|
start_login(host, autologin, autoname);
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *envinit[3];
|
||||||
|
|
||||||
|
void
|
||||||
|
init_env(void)
|
||||||
|
{
|
||||||
|
char **envp;
|
||||||
|
|
||||||
|
envp = envinit;
|
||||||
|
if ((*envp = getenv("TZ")))
|
||||||
|
*envp++ -= 3;
|
||||||
|
*envp = 0;
|
||||||
|
environ = envinit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* start_login(host)
|
||||||
|
*
|
||||||
|
* Assuming that we are now running as a child processes, this
|
||||||
|
* function will turn us into the login process.
|
||||||
|
*/
|
||||||
|
extern char *gettyname;
|
||||||
|
|
||||||
|
void
|
||||||
|
start_login(char *host, int autologin, char *name)
|
||||||
|
{
|
||||||
|
char **argv;
|
||||||
|
#define TABBUFSIZ 512
|
||||||
|
char defent[TABBUFSIZ];
|
||||||
|
char defstrs[TABBUFSIZ];
|
||||||
|
#undef TABBUFSIZ
|
||||||
|
const char *loginprog = NULL;
|
||||||
|
extern struct sockaddr_storage from;
|
||||||
|
char buf[sizeof(from) * 4 + 1];
|
||||||
|
|
||||||
|
scrub_env();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -a : pass on the address of the host.
|
||||||
|
* -h : pass on name of host.
|
||||||
|
* WARNING: -h and -a are accepted by login
|
||||||
|
* if and only if getuid() == 0.
|
||||||
|
* -p : don't clobber the environment (so terminal type stays set).
|
||||||
|
*
|
||||||
|
* -f : force this login, he has already been authenticated
|
||||||
|
*/
|
||||||
|
argv = addarg(0, "login");
|
||||||
|
|
||||||
|
argv = addarg(argv, "-a");
|
||||||
|
(void)strvisx(buf, (const char *)(const void *)&from, sizeof(from),
|
||||||
|
VIS_WHITE);
|
||||||
|
argv = addarg(argv, buf);
|
||||||
|
|
||||||
|
argv = addarg(argv, "-h");
|
||||||
|
argv = addarg(argv, host);
|
||||||
|
|
||||||
|
argv = addarg(argv, "-p");
|
||||||
|
#ifdef LINEMODE
|
||||||
|
/*
|
||||||
|
* Set the environment variable "LINEMODE" to either
|
||||||
|
* "real" or "kludge" if we are operating in either
|
||||||
|
* real or kludge linemode.
|
||||||
|
*/
|
||||||
|
if (lmodetype == REAL_LINEMODE)
|
||||||
|
setenv("LINEMODE", "real", 1);
|
||||||
|
# ifdef KLUDGELINEMODE
|
||||||
|
else if (lmodetype == KLUDGE_LINEMODE || lmodetype == KLUDGE_OK)
|
||||||
|
setenv("LINEMODE", "kludge", 1);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifdef SECURELOGIN
|
||||||
|
/*
|
||||||
|
* don't worry about the -f that might get sent.
|
||||||
|
* A -s is supposed to override it anyhow.
|
||||||
|
*/
|
||||||
|
if (require_secure_login)
|
||||||
|
argv = addarg(argv, "-s");
|
||||||
|
#endif
|
||||||
|
#ifdef AUTHENTICATION
|
||||||
|
if (auth_level >= 0 && autologin == AUTH_VALID) {
|
||||||
|
argv = addarg(argv, "-f");
|
||||||
|
argv = addarg(argv, "--");
|
||||||
|
argv = addarg(argv, name);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
if (getenv("USER")) {
|
||||||
|
argv = addarg(argv, "--");
|
||||||
|
argv = addarg(argv, getenv("USER"));
|
||||||
|
/*
|
||||||
|
* Assume that login will set the USER variable
|
||||||
|
* correctly. For SysV systems, this means that
|
||||||
|
* USER will no longer be set, just LOGNAME by
|
||||||
|
* login. (The problem is that if the auto-login
|
||||||
|
* fails, and the user then specifies a different
|
||||||
|
* account name, he can get logged in with both
|
||||||
|
* LOGNAME and USER in his environment, but the
|
||||||
|
* USER value will be wrong.
|
||||||
|
*/
|
||||||
|
unsetenv("USER");
|
||||||
|
}
|
||||||
|
if (getent(defent, gettyname) == 1) {
|
||||||
|
char *cp = defstrs;
|
||||||
|
|
||||||
|
loginprog = getstr("lo", &cp);
|
||||||
|
}
|
||||||
|
if (loginprog == NULL)
|
||||||
|
loginprog = _PATH_LOGIN;
|
||||||
|
closelog();
|
||||||
|
/*
|
||||||
|
* This sleep(1) is in here so that telnetd can
|
||||||
|
* finish up with the tty. There's a race condition
|
||||||
|
* the login banner message gets lost...
|
||||||
|
*/
|
||||||
|
sleep(1);
|
||||||
|
execv(loginprog, argv);
|
||||||
|
|
||||||
|
syslog(LOG_ERR, "%s: %m", loginprog);
|
||||||
|
fatalperror(net, loginprog);
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
|
||||||
|
char **
|
||||||
|
addarg(char **argv, const char *val)
|
||||||
|
{
|
||||||
|
char **cpp;
|
||||||
|
char **nargv;
|
||||||
|
|
||||||
|
if (argv == NULL) {
|
||||||
|
/*
|
||||||
|
* 10 entries, a leading length, and a null
|
||||||
|
*/
|
||||||
|
argv = malloc(sizeof(*argv) * 12);
|
||||||
|
if (argv == NULL)
|
||||||
|
return(NULL);
|
||||||
|
*argv++ = (char *)10;
|
||||||
|
*argv = (char *)0;
|
||||||
|
}
|
||||||
|
for (cpp = argv; *cpp; cpp++)
|
||||||
|
;
|
||||||
|
if (cpp == &argv[(long)argv[-1]]) {
|
||||||
|
--argv;
|
||||||
|
nargv = realloc(argv, sizeof(*argv) * ((long)(*argv) + 10 + 2));
|
||||||
|
if (nargv == NULL) {
|
||||||
|
fatal(net, "not enough memory");
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
argv = nargv;
|
||||||
|
*argv = (char *)((long)(*argv) + 10);
|
||||||
|
argv++;
|
||||||
|
cpp = &argv[(long)argv[-1] - 10];
|
||||||
|
}
|
||||||
|
*cpp++ = __UNCONST(val);
|
||||||
|
*cpp = 0;
|
||||||
|
return(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* scrub_env()
|
||||||
|
*
|
||||||
|
* We only accept the environment variables listed below.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
scrub_env(void)
|
||||||
|
{
|
||||||
|
static const char *reject[] = {
|
||||||
|
"TERMCAP=/",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *acceptstr[] = {
|
||||||
|
"XAUTH=", "XAUTHORITY=", "DISPLAY=",
|
||||||
|
"TERM=",
|
||||||
|
"EDITOR=",
|
||||||
|
"PAGER=",
|
||||||
|
"LOGNAME=",
|
||||||
|
"POSIXLY_CORRECT=",
|
||||||
|
"TERMCAP=",
|
||||||
|
"PRINTER=",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
char **cpp, **cpp2;
|
||||||
|
const char **p;
|
||||||
|
|
||||||
|
for (cpp2 = cpp = environ; *cpp; cpp++) {
|
||||||
|
int reject_it = 0;
|
||||||
|
|
||||||
|
for(p = reject; *p; p++)
|
||||||
|
if(strncmp(*cpp, *p, strlen(*p)) == 0) {
|
||||||
|
reject_it = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (reject_it)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for(p = acceptstr; *p; p++)
|
||||||
|
if(strncmp(*cpp, *p, strlen(*p)) == 0)
|
||||||
|
break;
|
||||||
|
if(*p != NULL)
|
||||||
|
*cpp2++ = *cpp;
|
||||||
|
}
|
||||||
|
*cpp2 = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cleanup()
|
||||||
|
*
|
||||||
|
* This is the routine to call when we are all through, to
|
||||||
|
* clean up anything that needs to be cleaned up.
|
||||||
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
|
void
|
||||||
|
cleanup(int sig)
|
||||||
|
{
|
||||||
|
char *p, c;
|
||||||
|
|
||||||
|
p = line + sizeof(_PATH_DEV) - 1;
|
||||||
|
#ifdef SUPPORT_UTMP
|
||||||
|
if (logout(p))
|
||||||
|
logwtmp(p, "", "");
|
||||||
|
#endif
|
||||||
|
#ifdef SUPPORT_UTMPX
|
||||||
|
if (logoutx(p, 0, DEAD_PROCESS))
|
||||||
|
logwtmpx(p, "", "", 0, DEAD_PROCESS);
|
||||||
|
#endif
|
||||||
|
(void)chmod(line, 0666);
|
||||||
|
(void)chown(line, 0, 0);
|
||||||
|
c = *p; *p = 'p';
|
||||||
|
(void)chmod(line, 0666);
|
||||||
|
(void)chown(line, 0, 0);
|
||||||
|
*p = c;
|
||||||
|
if (ttyaction(line, "telnetd", "root"))
|
||||||
|
syslog(LOG_ERR, "%s: ttyaction failed", line);
|
||||||
|
(void) shutdown(net, 2);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
591
libexec/telnetd/telnetd.8
Normal file
591
libexec/telnetd/telnetd.8
Normal file
|
|
@ -0,0 +1,591 @@
|
||||||
|
.\" $NetBSD: telnetd.8,v 1.31 2009/04/08 13:36:32 joerg Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1983, 1993
|
||||||
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. Neither the name of the University nor the names of its contributors
|
||||||
|
.\" may be used to endorse or promote products derived from this software
|
||||||
|
.\" without specific prior written permission.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" from: @(#)telnetd.8 8.3 (Berkeley) 3/1/94
|
||||||
|
.\"
|
||||||
|
.Dd July 17, 2004
|
||||||
|
.Dt TELNETD 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm telnetd
|
||||||
|
.Nd DARPA
|
||||||
|
.Tn TELNET
|
||||||
|
protocol server
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm /usr/libexec/telnetd
|
||||||
|
.Op Fl Uhlkns46
|
||||||
|
.Op Fl D Ar debugmode
|
||||||
|
.Op Fl S Ar tos
|
||||||
|
.Op Fl X Ar authtype
|
||||||
|
.Op Fl a Ar authmode
|
||||||
|
.Op Fl edebug
|
||||||
|
.Op Fl g Ar gettyent
|
||||||
|
.Op Fl u Ar len
|
||||||
|
.Op Fl debug Op Ar port
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
command is a server which supports the
|
||||||
|
.Tn DARPA
|
||||||
|
standard
|
||||||
|
.Tn TELNET
|
||||||
|
virtual terminal protocol.
|
||||||
|
.Nm
|
||||||
|
is normally invoked by the internet server (see
|
||||||
|
.Xr inetd 8 )
|
||||||
|
for requests to connect to the
|
||||||
|
.Tn TELNET
|
||||||
|
port as indicated by the
|
||||||
|
.Pa /etc/services
|
||||||
|
file (see
|
||||||
|
.Xr services 5 ) .
|
||||||
|
The
|
||||||
|
.Fl debug
|
||||||
|
option may be used to start up
|
||||||
|
.Nm
|
||||||
|
manually, instead of through
|
||||||
|
.Xr inetd 8 .
|
||||||
|
If started up this way,
|
||||||
|
.Ar port
|
||||||
|
may be specified to run
|
||||||
|
.Nm
|
||||||
|
on an alternate
|
||||||
|
.Tn TCP
|
||||||
|
port number.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
command accepts the following options:
|
||||||
|
.Bl -tag -width "-a authmode"
|
||||||
|
.It Fl a Ar authmode
|
||||||
|
This option may be used for specifying what mode should
|
||||||
|
be used for authentication.
|
||||||
|
Note that this option is only useful if
|
||||||
|
.Nm
|
||||||
|
has been compiled with support for the
|
||||||
|
.Dv AUTHENTICATION
|
||||||
|
option.
|
||||||
|
There are several valid values for
|
||||||
|
.Ar authmode :
|
||||||
|
.Bl -tag -width debug
|
||||||
|
.It debug
|
||||||
|
Turns on authentication debugging code.
|
||||||
|
.It user
|
||||||
|
Only allow connections when the remote user
|
||||||
|
can provide valid authentication information
|
||||||
|
to identify the remote user,
|
||||||
|
and is allowed access to the specified account
|
||||||
|
without providing a password.
|
||||||
|
.It valid
|
||||||
|
Only allow connections when the remote user
|
||||||
|
can provide valid authentication information
|
||||||
|
to identify the remote user.
|
||||||
|
The
|
||||||
|
.Xr login 1
|
||||||
|
command will provide any additional user verification
|
||||||
|
needed if the remote user is not allowed automatic
|
||||||
|
access to the specified account.
|
||||||
|
.It other
|
||||||
|
Only allow connections that supply some authentication information.
|
||||||
|
This option is currently not supported
|
||||||
|
by any of the existing authentication mechanisms,
|
||||||
|
and is thus the same as specifying
|
||||||
|
.Fl a
|
||||||
|
.Cm valid .
|
||||||
|
.It none
|
||||||
|
This is the default state.
|
||||||
|
Authentication information is not required.
|
||||||
|
If no or insufficient authentication information
|
||||||
|
is provided, then the
|
||||||
|
.Xr login 1
|
||||||
|
program will provide the necessary user
|
||||||
|
verification.
|
||||||
|
.It off
|
||||||
|
This disables the authentication code.
|
||||||
|
All user verification will happen through the
|
||||||
|
.Xr login 1
|
||||||
|
program.
|
||||||
|
.El
|
||||||
|
.It Fl D Ar debugmode
|
||||||
|
This option may be used for debugging purposes.
|
||||||
|
This allows
|
||||||
|
.Nm
|
||||||
|
to print out debugging information
|
||||||
|
to the connection, allowing the user to see what
|
||||||
|
.Nm
|
||||||
|
is doing.
|
||||||
|
There are several possible values for
|
||||||
|
.Ar debugmode :
|
||||||
|
.Bl -tag -width exercise
|
||||||
|
.It Cm options
|
||||||
|
Prints information about the negotiation of
|
||||||
|
.Tn TELNET
|
||||||
|
options.
|
||||||
|
.It Cm report
|
||||||
|
Prints the
|
||||||
|
.Cm options
|
||||||
|
information, plus some additional information
|
||||||
|
about what processing is going on.
|
||||||
|
.It Cm netdata
|
||||||
|
Displays the data stream received by
|
||||||
|
.Nm .
|
||||||
|
.It Cm ptydata
|
||||||
|
Displays data written to the pty.
|
||||||
|
.It Cm exercise
|
||||||
|
Has not been implemented yet.
|
||||||
|
.El
|
||||||
|
.It Fl debug
|
||||||
|
Enables debugging on each socket created by
|
||||||
|
.Nm
|
||||||
|
(see
|
||||||
|
.Dv SO_DEBUG
|
||||||
|
in
|
||||||
|
.Xr socket 2 ) .
|
||||||
|
.It Fl edebug
|
||||||
|
If
|
||||||
|
.Nm
|
||||||
|
has been compiled with support for data encryption, then the
|
||||||
|
.Fl edebug
|
||||||
|
option may be used to enable encryption debugging code.
|
||||||
|
.It Fl g Ar gettyent
|
||||||
|
Specifies which entry from
|
||||||
|
.Pa /etc/gettytab
|
||||||
|
should be used to get banner strings, login program and
|
||||||
|
other information.
|
||||||
|
The default entry is
|
||||||
|
.Dv default .
|
||||||
|
.It Fl h
|
||||||
|
Disables the printing of host-specific information before
|
||||||
|
login has been completed.
|
||||||
|
.It Fl k
|
||||||
|
This option is only useful if
|
||||||
|
.Nm
|
||||||
|
has been compiled with both linemode and kludge linemode support.
|
||||||
|
If the
|
||||||
|
.Fl k
|
||||||
|
option is specified,
|
||||||
|
then if the remote client does not support the
|
||||||
|
.Dv LINEMODE
|
||||||
|
option, then
|
||||||
|
.Nm
|
||||||
|
will operate in character at a time mode.
|
||||||
|
It will still support kludge linemode, but will only
|
||||||
|
go into kludge linemode if the remote client requests it.
|
||||||
|
(This is done by by the client sending
|
||||||
|
.Dv DONT SUPPRESS-GO-AHEAD
|
||||||
|
and
|
||||||
|
.Dv DONT ECHO . )
|
||||||
|
The
|
||||||
|
.Fl k
|
||||||
|
option is most useful when there are remote clients
|
||||||
|
that do not support kludge linemode, but pass the heuristic
|
||||||
|
(if they respond with
|
||||||
|
.Dv WILL TIMING-MARK
|
||||||
|
in response to a
|
||||||
|
.Dv DO TIMING-MARK )
|
||||||
|
for kludge linemode support.
|
||||||
|
.It Fl l
|
||||||
|
Specifies line mode.
|
||||||
|
Tries to force clients to use line-at-a-time mode.
|
||||||
|
If the
|
||||||
|
.Dv LINEMODE
|
||||||
|
option is not supported, it will go
|
||||||
|
into kludge linemode.
|
||||||
|
.It Fl n
|
||||||
|
Disable
|
||||||
|
.Dv TCP
|
||||||
|
keep-alives.
|
||||||
|
Normally
|
||||||
|
.Nm
|
||||||
|
enables the
|
||||||
|
.Tn TCP
|
||||||
|
keep-alive mechanism to probe connections that
|
||||||
|
have been idle for some period of time to determine
|
||||||
|
if the client is still there, so that idle connections
|
||||||
|
from machines that have crashed or can no longer
|
||||||
|
be reached may be cleaned up.
|
||||||
|
.It Fl s
|
||||||
|
This option is only enabled if
|
||||||
|
.Nm
|
||||||
|
is compiled with support for secure logins.
|
||||||
|
It causes the
|
||||||
|
.Fl s
|
||||||
|
option to be passed on to
|
||||||
|
.Xr login 1 ,
|
||||||
|
and thus is only useful if
|
||||||
|
.Xr login 1
|
||||||
|
supports the
|
||||||
|
.Fl s
|
||||||
|
flag to indicate that only Kerberos or S/Key
|
||||||
|
validated logins are allowed, and is
|
||||||
|
usually useful for controlling remote logins
|
||||||
|
from outside of a firewall.
|
||||||
|
.It Fl S Ar tos
|
||||||
|
This option sets the IP Type-of Service (TOS) option
|
||||||
|
on the connection to the value tos, which may be a
|
||||||
|
numeric TOS value or a symbolic TOS name found in the
|
||||||
|
.Pa /etc/iptos
|
||||||
|
file.
|
||||||
|
This option has no effect on
|
||||||
|
.Nx .
|
||||||
|
.\"The option has no effect on systems that do not
|
||||||
|
.\"support
|
||||||
|
.\".Xr parsetos 3
|
||||||
|
.\"routine and the
|
||||||
|
.\".Pa /etc/iptos
|
||||||
|
.\"file.
|
||||||
|
.It Fl u Ar len
|
||||||
|
This option is used to specify the size of the field
|
||||||
|
in the
|
||||||
|
.Dv utmp
|
||||||
|
structure that holds the remote host name.
|
||||||
|
If the resolved host name is longer than
|
||||||
|
.Ar len ,
|
||||||
|
the dotted decimal value will be used instead.
|
||||||
|
This allows hosts with very long host names that
|
||||||
|
overflow this field to still be uniquely identified.
|
||||||
|
Specifying
|
||||||
|
.Fl u0
|
||||||
|
indicates that only dotted decimal addresses
|
||||||
|
should be put into the
|
||||||
|
.Pa utmp
|
||||||
|
file.
|
||||||
|
.It Fl U
|
||||||
|
This option causes
|
||||||
|
.Nm
|
||||||
|
to refuse connections from addresses that
|
||||||
|
cannot be mapped back into a symbolic name via the
|
||||||
|
.Xr getnameinfo 3
|
||||||
|
routine.
|
||||||
|
.It Fl X Ar authtype
|
||||||
|
This option is only valid if
|
||||||
|
.Nm
|
||||||
|
has been built with support for the authentication option.
|
||||||
|
It disables the use of
|
||||||
|
.Ar authtype
|
||||||
|
authentication, and can be used to temporarily disable
|
||||||
|
a specific authentication type without having to recompile
|
||||||
|
.Nm .
|
||||||
|
.It Fl 4
|
||||||
|
.It Fl 6
|
||||||
|
Specifies address family to be used on
|
||||||
|
.Fl debug
|
||||||
|
mode.
|
||||||
|
During normal operation
|
||||||
|
.Po
|
||||||
|
called from
|
||||||
|
.Xr inetd 8
|
||||||
|
.Pc
|
||||||
|
.Nm
|
||||||
|
will use the file descriptor passed from
|
||||||
|
.Xr inetd 8 .
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
.Nm
|
||||||
|
operates by allocating a pseudo-terminal device (see
|
||||||
|
.Xr pty 4 )
|
||||||
|
for a client, then creating a login process which has
|
||||||
|
the slave side of the pseudo-terminal as
|
||||||
|
.Dv stdin ,
|
||||||
|
.Dv stdout
|
||||||
|
and
|
||||||
|
.Dv stderr .
|
||||||
|
.Nm
|
||||||
|
manipulates the master side of the pseudo-terminal,
|
||||||
|
implementing the
|
||||||
|
.Tn TELNET
|
||||||
|
protocol and passing characters
|
||||||
|
between the remote client and the login process.
|
||||||
|
.Pp
|
||||||
|
When a
|
||||||
|
.Tn TELNET
|
||||||
|
session is started up,
|
||||||
|
.Nm
|
||||||
|
sends
|
||||||
|
.Tn TELNET
|
||||||
|
options to the client side indicating
|
||||||
|
a willingness to do the following
|
||||||
|
.Tn TELNET
|
||||||
|
options, which are described in more detail below:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
DO AUTHENTICATION
|
||||||
|
WILL ENCRYPT
|
||||||
|
DO TERMINAL TYPE
|
||||||
|
DO TSPEED
|
||||||
|
DO XDISPLOC
|
||||||
|
DO NEW-ENVIRON
|
||||||
|
DO ENVIRON
|
||||||
|
WILL SUPPRESS GO AHEAD
|
||||||
|
DO ECHO
|
||||||
|
DO LINEMODE
|
||||||
|
DO NAWS
|
||||||
|
WILL STATUS
|
||||||
|
DO LFLOW
|
||||||
|
DO TIMING-MARK
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The pseudo-terminal allocated to the client is configured
|
||||||
|
to operate in \*(lqcooked\*(rq mode, and with
|
||||||
|
.Dv XTABS and
|
||||||
|
.Dv CRMOD
|
||||||
|
enabled (see
|
||||||
|
.Xr tty 4 ) .
|
||||||
|
.Pp
|
||||||
|
.Nm
|
||||||
|
has support for enabling locally the following
|
||||||
|
.Tn TELNET
|
||||||
|
options:
|
||||||
|
.Bl -tag -width "DO AUTHENTICATION"
|
||||||
|
.It "WILL ECHO"
|
||||||
|
When the
|
||||||
|
.Dv LINEMODE
|
||||||
|
option is enabled, a
|
||||||
|
.Dv WILL ECHO
|
||||||
|
or
|
||||||
|
.Dv WONT ECHO
|
||||||
|
will be sent to the client to indicate the
|
||||||
|
current state of terminal echoing.
|
||||||
|
When terminal echo is not desired, a
|
||||||
|
.Dv WILL ECHO
|
||||||
|
is sent to indicate that
|
||||||
|
.Tn telnetd
|
||||||
|
will take care of echoing any data that needs to be
|
||||||
|
echoed to the terminal, and then nothing is echoed.
|
||||||
|
When terminal echo is desired, a
|
||||||
|
.Dv WONT ECHO
|
||||||
|
is sent to indicate that
|
||||||
|
.Tn telnetd
|
||||||
|
will not be doing any terminal echoing, so the
|
||||||
|
client should do any terminal echoing that is needed.
|
||||||
|
.It "WILL BINARY"
|
||||||
|
Indicates that the client is willing to send a
|
||||||
|
8 bits of data, rather than the normal 7 bits
|
||||||
|
of the Network Virtual Terminal.
|
||||||
|
.It "WILL SGA"
|
||||||
|
Indicates that it will not be sending
|
||||||
|
.Dv IAC GA ,
|
||||||
|
go ahead, commands.
|
||||||
|
.It "WILL STATUS"
|
||||||
|
Indicates a willingness to send the client, upon
|
||||||
|
request, of the current status of all
|
||||||
|
.Tn TELNET
|
||||||
|
options.
|
||||||
|
.It "WILL TIMING-MARK"
|
||||||
|
Whenever a
|
||||||
|
.Dv DO TIMING-MARK
|
||||||
|
command is received, it is always responded
|
||||||
|
to with a
|
||||||
|
.Dv WILL TIMING-MARK
|
||||||
|
.It "WILL LOGOUT"
|
||||||
|
When a
|
||||||
|
.Dv DO LOGOUT
|
||||||
|
is received, a
|
||||||
|
.Dv WILL LOGOUT
|
||||||
|
is sent in response, and the
|
||||||
|
.Tn TELNET
|
||||||
|
session is shut down.
|
||||||
|
.It "WILL ENCRYPT"
|
||||||
|
Only sent if
|
||||||
|
.Nm
|
||||||
|
is compiled with support for data encryption, and
|
||||||
|
indicates a willingness to decrypt the data stream.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
.Nm
|
||||||
|
has support for enabling remotely the following
|
||||||
|
.Tn TELNET
|
||||||
|
options:
|
||||||
|
.Bl -tag -width "DO AUTHENTICATION"
|
||||||
|
.It "DO BINARY"
|
||||||
|
Sent to indicate that
|
||||||
|
.Tn telnetd
|
||||||
|
is willing to receive an 8 bit data stream.
|
||||||
|
.It "DO LFLOW"
|
||||||
|
Requests that the client handle flow control
|
||||||
|
characters remotely.
|
||||||
|
.It "DO ECHO"
|
||||||
|
This is not really supported, but is sent to identify a
|
||||||
|
.Bx 4.2
|
||||||
|
.Xr telnet 1
|
||||||
|
client, which will improperly respond with
|
||||||
|
.Dv WILL ECHO .
|
||||||
|
If a
|
||||||
|
.Dv WILL ECHO
|
||||||
|
is received, a
|
||||||
|
.Dv DONT ECHO
|
||||||
|
will be sent in response.
|
||||||
|
.It "DO TERMINAL-TYPE"
|
||||||
|
Indicates a desire to be able to request the
|
||||||
|
name of the type of terminal that is attached
|
||||||
|
to the client side of the connection.
|
||||||
|
.It "DO SGA"
|
||||||
|
Indicates that it does not need to receive
|
||||||
|
.Dv IAC GA ,
|
||||||
|
the go ahead command.
|
||||||
|
.It "DO NAWS"
|
||||||
|
Requests that the client inform the server when
|
||||||
|
the window (display) size changes.
|
||||||
|
.It "DO TERMINAL-SPEED"
|
||||||
|
Indicates a desire to be able to request information
|
||||||
|
about the speed of the serial line to which
|
||||||
|
the client is attached.
|
||||||
|
.It "DO XDISPLOC"
|
||||||
|
Indicates a desire to be able to request the name
|
||||||
|
of the X windows display that is associated with
|
||||||
|
the telnet client.
|
||||||
|
.It "DO NEW-ENVIRON"
|
||||||
|
Indicates a desire to be able to request environment
|
||||||
|
variable information, as described in RFC 1572.
|
||||||
|
.It "DO ENVIRON"
|
||||||
|
Indicates a desire to be able to request environment
|
||||||
|
variable information, as described in RFC 1408.
|
||||||
|
.It "DO LINEMODE"
|
||||||
|
Only sent if
|
||||||
|
.Nm
|
||||||
|
is compiled with support for linemode, and
|
||||||
|
requests that the client do line by line processing.
|
||||||
|
.It "DO TIMING-MARK"
|
||||||
|
Only sent if
|
||||||
|
.Nm
|
||||||
|
is compiled with support for both linemode and
|
||||||
|
kludge linemode, and the client responded with
|
||||||
|
.Dv WONT LINEMODE .
|
||||||
|
If the client responds with
|
||||||
|
.Dv WILL TM ,
|
||||||
|
the it is assumed that the client supports kludge linemode.
|
||||||
|
Note that the
|
||||||
|
.Op Fl k
|
||||||
|
option can be used to disable this.
|
||||||
|
.It "DO AUTHENTICATION"
|
||||||
|
Only sent if
|
||||||
|
.Nm
|
||||||
|
is compiled with support for authentication, and
|
||||||
|
indicates a willingness to receive authentication
|
||||||
|
information for automatic login.
|
||||||
|
.It "DO ENCRYPT"
|
||||||
|
Only sent if
|
||||||
|
.Nm
|
||||||
|
is compiled with support for data encryption, and
|
||||||
|
indicates a willingness to decrypt the data stream.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
At the end of a login session,
|
||||||
|
.Nm
|
||||||
|
invokes the
|
||||||
|
.Xr ttyaction 3
|
||||||
|
facility with an action of "telnetd" and user "root"
|
||||||
|
to execute site-specific commands.
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -item -compact
|
||||||
|
.It
|
||||||
|
.Pa /etc/services
|
||||||
|
.It
|
||||||
|
.Pa /etc/iptos
|
||||||
|
(if supported)
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr login 1 ,
|
||||||
|
.Xr skey 1 ,
|
||||||
|
.Xr telnet 1 ,
|
||||||
|
.Xr ttyaction 3
|
||||||
|
.Sh STANDARDS
|
||||||
|
.Bl -tag -compact -width "RFC 1572 "
|
||||||
|
.It RFC 854
|
||||||
|
.Tn TELNET
|
||||||
|
PROTOCOL SPECIFICATION
|
||||||
|
.It RFC 855
|
||||||
|
TELNET OPTION SPECIFICATIONS
|
||||||
|
.It RFC 856
|
||||||
|
TELNET BINARY TRANSMISSION
|
||||||
|
.It RFC 857
|
||||||
|
TELNET ECHO OPTION
|
||||||
|
.It RFC 858
|
||||||
|
TELNET SUPPRESS GO AHEAD OPTION
|
||||||
|
.It RFC 859
|
||||||
|
TELNET STATUS OPTION
|
||||||
|
.It RFC 860
|
||||||
|
TELNET TIMING MARK OPTION
|
||||||
|
.It RFC 861
|
||||||
|
TELNET EXTENDED OPTIONS - LIST OPTION
|
||||||
|
.It RFC 885
|
||||||
|
TELNET END OF RECORD OPTION
|
||||||
|
.It RFC 1073
|
||||||
|
Telnet Window Size Option
|
||||||
|
.It RFC 1079
|
||||||
|
Telnet Terminal Speed Option
|
||||||
|
.It RFC 1091
|
||||||
|
Telnet Terminal-Type Option
|
||||||
|
.It RFC 1096
|
||||||
|
Telnet X Display Location Option
|
||||||
|
.It RFC 1123
|
||||||
|
Requirements for Internet Hosts -- Application and Support
|
||||||
|
.It RFC 1184
|
||||||
|
Telnet Linemode Option
|
||||||
|
.It RFC 1372
|
||||||
|
Telnet Remote Flow Control Option
|
||||||
|
.It RFC 1416
|
||||||
|
Telnet Authentication Option
|
||||||
|
.It RFC 1411
|
||||||
|
Telnet Authentication: Kerberos Version 4
|
||||||
|
.It RFC 1412
|
||||||
|
Telnet Authentication: SPX
|
||||||
|
.It RFC 1571
|
||||||
|
Telnet Environment Option Interoperability Issues
|
||||||
|
.It RFC 1572
|
||||||
|
Telnet Environment Option
|
||||||
|
.El
|
||||||
|
.Sh BUGS
|
||||||
|
Some
|
||||||
|
.Tn TELNET
|
||||||
|
commands are only partially implemented.
|
||||||
|
.Pp
|
||||||
|
Because of bugs in the original
|
||||||
|
.Bx 4.2
|
||||||
|
.Xr telnet 1 ,
|
||||||
|
.Nm
|
||||||
|
performs some dubious protocol exchanges to try to discover if the remote
|
||||||
|
client is, in fact, a
|
||||||
|
.Bx 4.2
|
||||||
|
.Xr telnet 1 .
|
||||||
|
.Pp
|
||||||
|
Binary mode
|
||||||
|
has no common interpretation except between similar operating systems
|
||||||
|
.Po
|
||||||
|
.Ux
|
||||||
|
in this case
|
||||||
|
.Pc .
|
||||||
|
.Pp
|
||||||
|
The terminal type name received from the remote client is converted to
|
||||||
|
lower case.
|
||||||
|
.Pp
|
||||||
|
.Nm
|
||||||
|
never sends
|
||||||
|
.Tn TELNET
|
||||||
|
.Dv IAC GA
|
||||||
|
(go ahead) commands.
|
||||||
1159
libexec/telnetd/telnetd.c
Normal file
1159
libexec/telnetd/telnetd.c
Normal file
File diff suppressed because it is too large
Load Diff
45
libexec/telnetd/telnetd.h
Normal file
45
libexec/telnetd/telnetd.h
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
/* $NetBSD: telnetd.h,v 1.8 2003/08/07 09:46:52 agc Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* from: @(#)telnetd.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <defs.h>
|
||||||
|
#include <ext.h>
|
||||||
|
|
||||||
|
#ifdef DIAGNOSTICS
|
||||||
|
#define DIAG(a,b) if (diagnostic & (a)) b
|
||||||
|
#else
|
||||||
|
#define DIAG(a,b)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* other external variables */
|
||||||
|
extern char **environ;
|
||||||
620
libexec/telnetd/termstat.c
Normal file
620
libexec/telnetd/termstat.c
Normal file
|
|
@ -0,0 +1,620 @@
|
||||||
|
/* $NetBSD: termstat.c,v 1.14 2005/02/06 05:58:21 perry Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)termstat.c 8.2 (Berkeley) 5/30/95";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: termstat.c,v 1.14 2005/02/06 05:58:21 perry Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#include "telnetd.h"
|
||||||
|
|
||||||
|
#ifdef ENCRYPTION
|
||||||
|
#include <libtelnet/encrypt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* local variables
|
||||||
|
*/
|
||||||
|
int def_tspeed = -1, def_rspeed = -1;
|
||||||
|
int def_row = 0, def_col = 0;
|
||||||
|
#ifdef LINEMODE
|
||||||
|
static int _terminit = 0;
|
||||||
|
#endif /* LINEMODE */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LINEMODE
|
||||||
|
/*
|
||||||
|
* localstat
|
||||||
|
*
|
||||||
|
* This function handles all management of linemode.
|
||||||
|
*
|
||||||
|
* Linemode allows the client to do the local editing of data
|
||||||
|
* and send only complete lines to the server. Linemode state is
|
||||||
|
* based on the state of the pty driver. If the pty is set for
|
||||||
|
* external processing, then we can use linemode. Further, if we
|
||||||
|
* can use real linemode, then we can look at the edit control bits
|
||||||
|
* in the pty to determine what editing the client should do.
|
||||||
|
*
|
||||||
|
* Linemode support uses the following state flags to keep track of
|
||||||
|
* current and desired linemode state.
|
||||||
|
* alwayslinemode : true if -l was specified on the telnetd
|
||||||
|
* command line. It means to have linemode on as much as
|
||||||
|
* possible.
|
||||||
|
*
|
||||||
|
* lmodetype: signifies whether the client can
|
||||||
|
* handle real linemode, or if use of kludgeomatic linemode
|
||||||
|
* is preferred. It will be set to one of the following:
|
||||||
|
* REAL_LINEMODE : use linemode option
|
||||||
|
* NO_KLUDGE : don't initiate kludge linemode.
|
||||||
|
* KLUDGE_LINEMODE : use kludge linemode
|
||||||
|
* NO_LINEMODE : client is ignorant of linemode
|
||||||
|
*
|
||||||
|
* linemode, uselinemode : linemode is true if linemode
|
||||||
|
* is currently on, uselinemode is the state that we wish
|
||||||
|
* to be in. If another function wishes to turn linemode
|
||||||
|
* on or off, it sets or clears uselinemode.
|
||||||
|
*
|
||||||
|
* editmode, useeditmode : like linemode/uselinemode, but
|
||||||
|
* these contain the edit mode states (edit and trapsig).
|
||||||
|
*
|
||||||
|
* The state variables correspond to some of the state information
|
||||||
|
* in the pty.
|
||||||
|
* linemode:
|
||||||
|
* In real linemode, this corresponds to whether the pty
|
||||||
|
* expects external processing of incoming data.
|
||||||
|
* In kludge linemode, this more closely corresponds to the
|
||||||
|
* whether normal processing is on or not. (ICANON in
|
||||||
|
* system V, or COOKED mode in BSD.)
|
||||||
|
* If the -l option was specified (alwayslinemode), then
|
||||||
|
* an attempt is made to force external processing on at
|
||||||
|
* all times.
|
||||||
|
*
|
||||||
|
* The following heuristics are applied to determine linemode
|
||||||
|
* handling within the server.
|
||||||
|
* 1) Early on in starting up the server, an attempt is made
|
||||||
|
* to negotiate the linemode option. If this succeeds
|
||||||
|
* then lmodetype is set to REAL_LINEMODE and all linemode
|
||||||
|
* processing occurs in the context of the linemode option.
|
||||||
|
* 2) If the attempt to negotiate the linemode option failed,
|
||||||
|
* and the "-k" (don't initiate kludge linemode) isn't set,
|
||||||
|
* then we try to use kludge linemode. We test for this
|
||||||
|
* capability by sending "do Timing Mark". If a positive
|
||||||
|
* response comes back, then we assume that the client
|
||||||
|
* understands kludge linemode (ech!) and the
|
||||||
|
* lmodetype flag is set to KLUDGE_LINEMODE.
|
||||||
|
* 3) Otherwise, linemode is not supported at all and
|
||||||
|
* lmodetype remains set to NO_LINEMODE (which happens
|
||||||
|
* to be 0 for convenience).
|
||||||
|
* 4) At any time a command arrives that implies a higher
|
||||||
|
* state of linemode support in the client, we move to that
|
||||||
|
* linemode support.
|
||||||
|
*
|
||||||
|
* A short explanation of kludge linemode is in order here.
|
||||||
|
* 1) The heuristic to determine support for kludge linemode
|
||||||
|
* is to send a do timing mark. We assume that a client
|
||||||
|
* that supports timing marks also supports kludge linemode.
|
||||||
|
* A risky proposition at best.
|
||||||
|
* 2) Further negotiation of linemode is done by changing the
|
||||||
|
* the server's state regarding SGA. If server will SGA,
|
||||||
|
* then linemode is off, if server won't SGA, then linemode
|
||||||
|
* is on.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
localstat(void)
|
||||||
|
{
|
||||||
|
int need_will_echo = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for state of BINARY options.
|
||||||
|
*/
|
||||||
|
if (tty_isbinaryin()) {
|
||||||
|
if (his_want_state_is_wont(TELOPT_BINARY))
|
||||||
|
send_do(TELOPT_BINARY, 1);
|
||||||
|
} else {
|
||||||
|
if (his_want_state_is_will(TELOPT_BINARY))
|
||||||
|
send_dont(TELOPT_BINARY, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tty_isbinaryout()) {
|
||||||
|
if (my_want_state_is_wont(TELOPT_BINARY))
|
||||||
|
send_will(TELOPT_BINARY, 1);
|
||||||
|
} else {
|
||||||
|
if (my_want_state_is_will(TELOPT_BINARY))
|
||||||
|
send_wont(TELOPT_BINARY, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for changes to flow control if client supports it.
|
||||||
|
*/
|
||||||
|
flowstat();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check linemode on/off state
|
||||||
|
*/
|
||||||
|
uselinemode = tty_linemode();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If alwayslinemode is on, and pty is changing to turn it off, then
|
||||||
|
* force linemode back on.
|
||||||
|
*/
|
||||||
|
if (alwayslinemode && linemode && !uselinemode) {
|
||||||
|
uselinemode = 1;
|
||||||
|
tty_setlinemode(uselinemode);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENCRYPTION
|
||||||
|
/*
|
||||||
|
* If the terminal is not echoing, but editing is enabled,
|
||||||
|
* something like password input is going to happen, so
|
||||||
|
* if we the other side is not currently sending encrypted
|
||||||
|
* data, ask the other side to start encrypting.
|
||||||
|
*/
|
||||||
|
if (his_state_is_will(TELOPT_ENCRYPT)) {
|
||||||
|
static int enc_passwd = 0;
|
||||||
|
if (uselinemode && !tty_isecho() && tty_isediting()
|
||||||
|
&& (enc_passwd == 0) && !decrypt_input) {
|
||||||
|
encrypt_send_request_start();
|
||||||
|
enc_passwd = 1;
|
||||||
|
} else if (enc_passwd) {
|
||||||
|
encrypt_send_request_end();
|
||||||
|
enc_passwd = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* ENCRYPTION */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do echo mode handling as soon as we know what the
|
||||||
|
* linemode is going to be.
|
||||||
|
* If the pty has echo turned off, then tell the client that
|
||||||
|
* the server will echo. If echo is on, then the server
|
||||||
|
* will echo if in character mode, but in linemode the
|
||||||
|
* client should do local echoing. The state machine will
|
||||||
|
* not send anything if it is unnecessary, so don't worry
|
||||||
|
* about that here.
|
||||||
|
*
|
||||||
|
* If we need to send the WILL ECHO (because echo is off),
|
||||||
|
* then delay that until after we have changed the MODE.
|
||||||
|
* This way, when the user is turning off both editing
|
||||||
|
* and echo, the client will get editing turned off first.
|
||||||
|
* This keeps the client from going into encryption mode
|
||||||
|
* and then right back out if it is doing auto-encryption
|
||||||
|
* when passwords are being typed.
|
||||||
|
*/
|
||||||
|
if (uselinemode) {
|
||||||
|
if (tty_isecho())
|
||||||
|
send_wont(TELOPT_ECHO, 1);
|
||||||
|
else
|
||||||
|
need_will_echo = 1;
|
||||||
|
#ifdef KLUDGELINEMODE
|
||||||
|
if (lmodetype == KLUDGE_OK)
|
||||||
|
lmodetype = KLUDGE_LINEMODE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If linemode is being turned off, send appropriate
|
||||||
|
* command and then we're all done.
|
||||||
|
*/
|
||||||
|
if (!uselinemode && linemode) {
|
||||||
|
# ifdef KLUDGELINEMODE
|
||||||
|
if (lmodetype == REAL_LINEMODE) {
|
||||||
|
# endif /* KLUDGELINEMODE */
|
||||||
|
send_dont(TELOPT_LINEMODE, 1);
|
||||||
|
# ifdef KLUDGELINEMODE
|
||||||
|
} else if (lmodetype == KLUDGE_LINEMODE)
|
||||||
|
send_will(TELOPT_SGA, 1);
|
||||||
|
# endif /* KLUDGELINEMODE */
|
||||||
|
send_will(TELOPT_ECHO, 1);
|
||||||
|
linemode = uselinemode;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef KLUDGELINEMODE
|
||||||
|
/*
|
||||||
|
* If using real linemode check edit modes for possible later use.
|
||||||
|
* If we are in kludge linemode, do the SGA negotiation.
|
||||||
|
*/
|
||||||
|
if (lmodetype == REAL_LINEMODE) {
|
||||||
|
# endif /* KLUDGELINEMODE */
|
||||||
|
useeditmode = 0;
|
||||||
|
if (tty_isediting())
|
||||||
|
useeditmode |= MODE_EDIT;
|
||||||
|
if (tty_istrapsig())
|
||||||
|
useeditmode |= MODE_TRAPSIG;
|
||||||
|
if (tty_issofttab())
|
||||||
|
useeditmode |= MODE_SOFT_TAB;
|
||||||
|
if (tty_islitecho())
|
||||||
|
useeditmode |= MODE_LIT_ECHO;
|
||||||
|
# ifdef KLUDGELINEMODE
|
||||||
|
} else if (lmodetype == KLUDGE_LINEMODE) {
|
||||||
|
if (tty_isediting() && uselinemode)
|
||||||
|
send_wont(TELOPT_SGA, 1);
|
||||||
|
else
|
||||||
|
send_will(TELOPT_SGA, 1);
|
||||||
|
}
|
||||||
|
# endif /* KLUDGELINEMODE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Negotiate linemode on if pty state has changed to turn it on.
|
||||||
|
* Send appropriate command and send along edit mode, then all done.
|
||||||
|
*/
|
||||||
|
if (uselinemode && !linemode) {
|
||||||
|
# ifdef KLUDGELINEMODE
|
||||||
|
if (lmodetype == KLUDGE_LINEMODE) {
|
||||||
|
send_wont(TELOPT_SGA, 1);
|
||||||
|
} else if (lmodetype == REAL_LINEMODE) {
|
||||||
|
# endif /* KLUDGELINEMODE */
|
||||||
|
send_do(TELOPT_LINEMODE, 1);
|
||||||
|
/* send along edit modes */
|
||||||
|
(void) output_data("%c%c%c%c%c%c%c", IAC, SB,
|
||||||
|
TELOPT_LINEMODE, LM_MODE, useeditmode,
|
||||||
|
IAC, SE);
|
||||||
|
editmode = useeditmode;
|
||||||
|
# ifdef KLUDGELINEMODE
|
||||||
|
}
|
||||||
|
# endif /* KLUDGELINEMODE */
|
||||||
|
linemode = uselinemode;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef KLUDGELINEMODE
|
||||||
|
/*
|
||||||
|
* None of what follows is of any value if not using
|
||||||
|
* real linemode.
|
||||||
|
*/
|
||||||
|
if (lmodetype < REAL_LINEMODE)
|
||||||
|
goto done;
|
||||||
|
# endif /* KLUDGELINEMODE */
|
||||||
|
|
||||||
|
if (linemode && his_state_is_will(TELOPT_LINEMODE)) {
|
||||||
|
/*
|
||||||
|
* If edit mode changed, send edit mode.
|
||||||
|
*/
|
||||||
|
if (useeditmode != editmode) {
|
||||||
|
/*
|
||||||
|
* Send along appropriate edit mode mask.
|
||||||
|
*/
|
||||||
|
(void) output_data("%c%c%c%c%c%c%c", IAC, SB,
|
||||||
|
TELOPT_LINEMODE, LM_MODE, useeditmode,
|
||||||
|
IAC, SE);
|
||||||
|
editmode = useeditmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for changes to special characters in use.
|
||||||
|
*/
|
||||||
|
start_slc(0);
|
||||||
|
check_slc();
|
||||||
|
(void) end_slc(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (need_will_echo)
|
||||||
|
send_will(TELOPT_ECHO, 1);
|
||||||
|
/*
|
||||||
|
* Some things should be deferred until after the pty state has
|
||||||
|
* been set by the local process. Do those things that have been
|
||||||
|
* deferred now. This only happens once.
|
||||||
|
*/
|
||||||
|
if (_terminit == 0) {
|
||||||
|
_terminit = 1;
|
||||||
|
defer_terminit();
|
||||||
|
}
|
||||||
|
|
||||||
|
netflush();
|
||||||
|
set_termbuf();
|
||||||
|
return;
|
||||||
|
|
||||||
|
} /* end of localstat */
|
||||||
|
#endif /* LINEMODE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flowstat
|
||||||
|
*
|
||||||
|
* Check for changes to flow control
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
flowstat(void)
|
||||||
|
{
|
||||||
|
if (his_state_is_will(TELOPT_LFLOW)) {
|
||||||
|
if (tty_flowmode() != flowmode) {
|
||||||
|
flowmode = tty_flowmode();
|
||||||
|
(void) output_data("%c%c%c%c%c%c",
|
||||||
|
IAC, SB, TELOPT_LFLOW,
|
||||||
|
flowmode ? LFLOW_ON : LFLOW_OFF,
|
||||||
|
IAC, SE);
|
||||||
|
}
|
||||||
|
if (tty_restartany() != restartany) {
|
||||||
|
restartany = tty_restartany();
|
||||||
|
(void) output_data("%c%c%c%c%c%c",
|
||||||
|
IAC, SB, TELOPT_LFLOW,
|
||||||
|
restartany ? LFLOW_RESTART_ANY
|
||||||
|
: LFLOW_RESTART_XON,
|
||||||
|
IAC, SE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clientstat
|
||||||
|
*
|
||||||
|
* Process linemode related requests from the client.
|
||||||
|
* Client can request a change to only one of linemode, editmode or slc's
|
||||||
|
* at a time, and if using kludge linemode, then only linemode may be
|
||||||
|
* affected.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clientstat(int code, int parm1, int parm2)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a copy of terminal characteristics.
|
||||||
|
*/
|
||||||
|
init_termbuf();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process request from client. code tells what it is.
|
||||||
|
*/
|
||||||
|
switch (code) {
|
||||||
|
#ifdef LINEMODE
|
||||||
|
case TELOPT_LINEMODE:
|
||||||
|
/*
|
||||||
|
* Don't do anything unless client is asking us to change
|
||||||
|
* modes.
|
||||||
|
*/
|
||||||
|
uselinemode = (parm1 == WILL);
|
||||||
|
if (uselinemode != linemode) {
|
||||||
|
# ifdef KLUDGELINEMODE
|
||||||
|
/*
|
||||||
|
* If using kludge linemode, make sure that
|
||||||
|
* we can do what the client asks.
|
||||||
|
* We can not turn off linemode if alwayslinemode
|
||||||
|
* and the ICANON bit is set.
|
||||||
|
*/
|
||||||
|
if (lmodetype == KLUDGE_LINEMODE) {
|
||||||
|
if (alwayslinemode && tty_isediting()) {
|
||||||
|
uselinemode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Quit now if we can't do it.
|
||||||
|
*/
|
||||||
|
if (uselinemode == linemode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If using real linemode and linemode is being
|
||||||
|
* turned on, send along the edit mode mask.
|
||||||
|
*/
|
||||||
|
if (lmodetype == REAL_LINEMODE && uselinemode)
|
||||||
|
# else /* KLUDGELINEMODE */
|
||||||
|
if (uselinemode)
|
||||||
|
# endif /* KLUDGELINEMODE */
|
||||||
|
{
|
||||||
|
useeditmode = 0;
|
||||||
|
if (tty_isediting())
|
||||||
|
useeditmode |= MODE_EDIT;
|
||||||
|
if (tty_istrapsig())
|
||||||
|
useeditmode |= MODE_TRAPSIG;
|
||||||
|
if (tty_issofttab())
|
||||||
|
useeditmode |= MODE_SOFT_TAB;
|
||||||
|
if (tty_islitecho())
|
||||||
|
useeditmode |= MODE_LIT_ECHO;
|
||||||
|
(void) output_data("%c%c%c%c%c%c%c", IAC,
|
||||||
|
SB, TELOPT_LINEMODE, LM_MODE,
|
||||||
|
useeditmode, IAC, SE);
|
||||||
|
editmode = useeditmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tty_setlinemode(uselinemode);
|
||||||
|
|
||||||
|
linemode = uselinemode;
|
||||||
|
|
||||||
|
if (!linemode)
|
||||||
|
send_will(TELOPT_ECHO, 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LM_MODE:
|
||||||
|
{
|
||||||
|
int ack, changed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Client has sent along a mode mask. If it agrees with
|
||||||
|
* what we are currently doing, ignore it; if not, it could
|
||||||
|
* be viewed as a request to change. Note that the server
|
||||||
|
* will change to the modes in an ack if it is different from
|
||||||
|
* what we currently have, but we will not ack the ack.
|
||||||
|
*/
|
||||||
|
useeditmode &= MODE_MASK;
|
||||||
|
ack = (useeditmode & MODE_ACK);
|
||||||
|
useeditmode &= ~MODE_ACK;
|
||||||
|
|
||||||
|
if ((changed = (useeditmode ^ editmode))) {
|
||||||
|
/*
|
||||||
|
* This check is for a timing problem. If the
|
||||||
|
* state of the tty has changed (due to the user
|
||||||
|
* application) we need to process that info
|
||||||
|
* before we write in the state contained in the
|
||||||
|
* ack!!! This gets out the new MODE request,
|
||||||
|
* and when the ack to that command comes back
|
||||||
|
* we'll set it and be in the right mode.
|
||||||
|
*/
|
||||||
|
if (ack)
|
||||||
|
localstat();
|
||||||
|
if (changed & MODE_EDIT)
|
||||||
|
tty_setedit(useeditmode & MODE_EDIT);
|
||||||
|
|
||||||
|
if (changed & MODE_TRAPSIG)
|
||||||
|
tty_setsig(useeditmode & MODE_TRAPSIG);
|
||||||
|
|
||||||
|
if (changed & MODE_SOFT_TAB)
|
||||||
|
tty_setsofttab(useeditmode & MODE_SOFT_TAB);
|
||||||
|
|
||||||
|
if (changed & MODE_LIT_ECHO)
|
||||||
|
tty_setlitecho(useeditmode & MODE_LIT_ECHO);
|
||||||
|
|
||||||
|
set_termbuf();
|
||||||
|
|
||||||
|
if (!ack) {
|
||||||
|
(void) output_data("%c%c%c%c%c%c%c", IAC,
|
||||||
|
SB, TELOPT_LINEMODE, LM_MODE,
|
||||||
|
useeditmode|MODE_ACK,
|
||||||
|
IAC, SE);
|
||||||
|
}
|
||||||
|
|
||||||
|
editmode = useeditmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
} /* end of case LM_MODE */
|
||||||
|
#endif /* LINEMODE */
|
||||||
|
|
||||||
|
case TELOPT_NAWS:
|
||||||
|
{
|
||||||
|
struct winsize ws;
|
||||||
|
|
||||||
|
def_col = parm1;
|
||||||
|
def_row = parm2;
|
||||||
|
#ifdef LINEMODE
|
||||||
|
/*
|
||||||
|
* Defer changing window size until after terminal is
|
||||||
|
* initialized.
|
||||||
|
*/
|
||||||
|
if (terminit() == 0)
|
||||||
|
return;
|
||||||
|
#endif /* LINEMODE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change window size as requested by client.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ws.ws_col = parm1;
|
||||||
|
ws.ws_row = parm2;
|
||||||
|
(void) ioctl(pty, TIOCSWINSZ, (char *)&ws);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TELOPT_TSPEED:
|
||||||
|
{
|
||||||
|
def_tspeed = parm1;
|
||||||
|
def_rspeed = parm2;
|
||||||
|
#ifdef LINEMODE
|
||||||
|
/*
|
||||||
|
* Defer changing the terminal speed.
|
||||||
|
*/
|
||||||
|
if (terminit() == 0)
|
||||||
|
return;
|
||||||
|
#endif /* LINEMODE */
|
||||||
|
/*
|
||||||
|
* Change terminal speed as requested by client.
|
||||||
|
* We set the receive speed first, so that if we can't
|
||||||
|
* store separate receive and transmit speeds, the transmit
|
||||||
|
* speed will take precedence.
|
||||||
|
*/
|
||||||
|
tty_rspeed(parm2);
|
||||||
|
tty_tspeed(parm1);
|
||||||
|
set_termbuf();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
} /* end of case TELOPT_TSPEED */
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* What? */
|
||||||
|
break;
|
||||||
|
} /* end of switch */
|
||||||
|
|
||||||
|
|
||||||
|
netflush();
|
||||||
|
|
||||||
|
} /* end of clientstat */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LINEMODE
|
||||||
|
/*
|
||||||
|
* defer_terminit
|
||||||
|
*
|
||||||
|
* Some things should not be done until after the login process has started
|
||||||
|
* and all the pty modes are set to what they are supposed to be. This
|
||||||
|
* function is called when the pty state has been processed for the first time.
|
||||||
|
* It calls other functions that do things that were deferred in each module.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
defer_terminit(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* local stuff that got deferred.
|
||||||
|
*/
|
||||||
|
if (def_tspeed != -1) {
|
||||||
|
clientstat(TELOPT_TSPEED, def_tspeed, def_rspeed);
|
||||||
|
def_tspeed = def_rspeed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def_col || def_row) {
|
||||||
|
struct winsize ws;
|
||||||
|
|
||||||
|
memset((char *)&ws, 0, sizeof(ws));
|
||||||
|
ws.ws_col = def_col;
|
||||||
|
ws.ws_row = def_row;
|
||||||
|
(void) ioctl(pty, TIOCSWINSZ, (char *)&ws);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The only other module that currently defers anything.
|
||||||
|
*/
|
||||||
|
deferslc();
|
||||||
|
|
||||||
|
} /* end of defer_terminit */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* terminit
|
||||||
|
*
|
||||||
|
* Returns true if the pty state has been processed yet.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
terminit(void)
|
||||||
|
{
|
||||||
|
return(_terminit);
|
||||||
|
|
||||||
|
} /* end of terminit */
|
||||||
|
#endif /* LINEMODE */
|
||||||
1077
libexec/telnetd/utility.c
Normal file
1077
libexec/telnetd/utility.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user