summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2005-05-25 05:35:23 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2005-05-25 05:35:23 +0000
commitda59a2318f0f71de02a778d5bfa0e8c13ea567d4 (patch)
treeb14540db8c87f0d6c06df788a75a046184bda104 /libexec
parent8b49fb588584958bcb4dd4d561c276394bf21c4c (diff)
bye bye
Diffstat (limited to 'libexec')
-rw-r--r--libexec/telnetd/Makefile26
-rw-r--r--libexec/telnetd/auth-proto.h133
-rw-r--r--libexec/telnetd/auth.c664
-rw-r--r--libexec/telnetd/auth.h91
-rw-r--r--libexec/telnetd/authenc.c75
-rw-r--r--libexec/telnetd/defs.h182
-rw-r--r--libexec/telnetd/enc-proto.h153
-rw-r--r--libexec/telnetd/enc_des.c660
-rw-r--r--libexec/telnetd/encrypt.c1005
-rw-r--r--libexec/telnetd/encrypt.h105
-rw-r--r--libexec/telnetd/ext.h201
-rw-r--r--libexec/telnetd/genget.c104
-rw-r--r--libexec/telnetd/global.c105
-rw-r--r--libexec/telnetd/kerberos.c751
-rw-r--r--libexec/telnetd/kerberos5.c910
-rw-r--r--libexec/telnetd/mini_inetd.c136
-rw-r--r--libexec/telnetd/misc-proto.h90
-rw-r--r--libexec/telnetd/misc.c102
-rw-r--r--libexec/telnetd/misc.h40
-rw-r--r--libexec/telnetd/slc.c53
-rw-r--r--libexec/telnetd/socket.c55
-rw-r--r--libexec/telnetd/state.c1400
-rw-r--r--libexec/telnetd/sys_term.c1911
-rw-r--r--libexec/telnetd/telnetd.8537
-rw-r--r--libexec/telnetd/telnetd.c1398
-rw-r--r--libexec/telnetd/telnetd.h240
-rw-r--r--libexec/telnetd/termstat.c136
-rw-r--r--libexec/telnetd/utility.c1169
28 files changed, 0 insertions, 12432 deletions
diff --git a/libexec/telnetd/Makefile b/libexec/telnetd/Makefile
deleted file mode 100644
index f20366dff48..00000000000
--- a/libexec/telnetd/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# $OpenBSD: Makefile,v 1.22 2004/11/24 07:35:40 biorn Exp $
-# from: @(#)Makefile 8.2 (Berkeley) 12/15/93
-# $NetBSD: Makefile,v 1.6 1996/02/24 01:22:12 jtk Exp $
-
-PROG= telnetd
-
-CFLAGS+=-DLINEMODE -DKLUDGELINEMODE -DUSE_TERMIO -DDIAGNOSTICS
-CFLAGS+=-DOLD_ENVIRON -DENV_HACK -I${.CURDIR} -Wall
-CFLAGS+= -DHAS_CGETENT -Wno-unused
-SRCS= authenc.c global.c slc.c state.c sys_term.c telnetd.c \
- termstat.c utility.c mini_inetd.c socket.c \
- auth.c encrypt.c genget.c misc.c
-DPADD= ${LIBUTIL} ${LIBCURSES}
-LDADD+= -lutil -lcurses
-MAN= telnetd.8
-
-.include <bsd.own.mk> # for KERBEROS
-
-.if (${KERBEROS5:L} == "yes")
-CFLAGS+=-DENCRYPTION -DKRB5 -DAUTHENTICATION -DDES_ENCRYPTION -I${.CURDIR}/../../lib
-SRCS+= kerberos5.c enc_des.c
-DPADD+= ${LIBKRB5} ${LIBASN1} ${LIBCRYPTO} ${LIBDES}
-LDADD+= -lkrb5 -lasn1 -lcrypto -ldes
-.endif
-
-.include <bsd.prog.mk>
diff --git a/libexec/telnetd/auth-proto.h b/libexec/telnetd/auth-proto.h
deleted file mode 100644
index fb6487ab206..00000000000
--- a/libexec/telnetd/auth-proto.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*-
- * 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.
- *
- * from: @(#)auth-proto.h 8.1 (Berkeley) 6/4/93
- * $OpenBSD: auth-proto.h,v 1.2 2003/06/02 19:38:24 millert Exp $
- * $NetBSD: auth-proto.h,v 1.5 1996/02/24 01:15:16 jtk Exp $
- */
-
-/*
- * This source code is no longer held under any constraint of USA
- * `cryptographic laws' since it was exported legally. The cryptographic
- * functions were removed from the code and a "Bones" distribution was
- * made. A Commodity Jurisdiction Request #012-94 was filed with the
- * USA State Department, who handed it to the Commerce department. The
- * code was determined to fall under General License GTDA under ECCN 5D96G,
- * and hence exportable. The cryptographic interfaces were re-added by Eric
- * Young, and then KTH proceeded to maintain the code in the free world.
- *
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America is assumed
- * to require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#include <sys/cdefs.h>
-/* $KTH: auth-proto.h,v 1.10 2000/01/18 03:08:55 assar Exp $ */
-
-#if defined(AUTHENTICATION)
-Authenticator *findauthenticator (int, int);
-
-int auth_wait (char *, size_t);
-void auth_disable_name (char *);
-void auth_finished (Authenticator *, int);
-void auth_gen_printsub (unsigned char *, int, unsigned char *, int);
-void auth_init (const char *, int);
-void auth_is (unsigned char *, int);
-void auth_name (unsigned char*, int);
-void auth_reply (unsigned char *, int);
-void auth_request (void);
-void auth_send (unsigned char *, int);
-void auth_send_retry (void);
-void auth_printsub (unsigned char*, int, unsigned char*, int);
-int getauthmask (char *type, int *maskp);
-int auth_enable (char *type);
-int auth_disable (char *type);
-int auth_onoff (char *type, int on);
-int auth_togdebug (int on);
-int auth_status (void);
-int auth_sendname (unsigned char *cp, int len);
-void auth_debug (int mode);
-void auth_gen_printsub (unsigned char *data, int cnt,
- unsigned char *buf, int buflen);
-
-#ifdef UNSAFE
-int unsafe_init (Authenticator *, int);
-int unsafe_send (Authenticator *);
-void unsafe_is (Authenticator *, unsigned char *, int);
-void unsafe_reply (Authenticator *, unsigned char *, int);
-int unsafe_status (Authenticator *, char *, int);
-void unsafe_printsub (unsigned char *, int, unsigned char *, int);
-#endif
-
-#ifdef SRA
-int sra_init (Authenticator *, int);
-int sra_send (Authenticator *);
-void sra_is (Authenticator *, unsigned char *, int);
-void sra_reply (Authenticator *, unsigned char *, int);
-int sra_status (Authenticator *, char *, int);
-void sra_printsub (unsigned char *, int, unsigned char *, int);
-#endif
-
-#ifdef KRB4
-int kerberos4_init (Authenticator *, int);
-int kerberos4_send_mutual (Authenticator *);
-int kerberos4_send_oneway (Authenticator *);
-void kerberos4_is (Authenticator *, unsigned char *, int);
-void kerberos4_reply (Authenticator *, unsigned char *, int);
-int kerberos4_status (Authenticator *, char *, size_t, int);
-void kerberos4_printsub (unsigned char *, int, unsigned char *, int);
-int kerberos4_forward (Authenticator *ap, void *);
-#endif
-
-#ifdef KRB5
-int kerberos5_init (Authenticator *, int);
-int kerberos5_send_mutual (Authenticator *);
-int kerberos5_send_oneway (Authenticator *);
-void kerberos5_is (Authenticator *, unsigned char *, int);
-void kerberos5_reply (Authenticator *, unsigned char *, int);
-int kerberos5_status (Authenticator *, char *, size_t, int);
-void kerberos5_printsub (unsigned char *, int, unsigned char *, int);
-#endif
-#endif
diff --git a/libexec/telnetd/auth.c b/libexec/telnetd/auth.c
deleted file mode 100644
index 18705da78e7..00000000000
--- a/libexec/telnetd/auth.c
+++ /dev/null
@@ -1,664 +0,0 @@
-/* $OpenBSD: auth.c,v 1.2 2003/06/02 19:38:24 millert 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.
- */
-
-#ifndef lint
-/* from: static char sccsid[] = "@(#)auth.c 8.3 (Berkeley) 5/30/95" */
-/* from: static char *rcsid = "$NetBSD: auth.c,v 1.5 1996/02/24 01:15:17 jtk Exp $"; */
-#endif /* not lint */
-
-/*
- * This source code is no longer held under any constraint of USA
- * `cryptographic laws' since it was exported legally. The cryptographic
- * functions were removed from the code and a "Bones" distribution was
- * made. A Commodity Jurisdiction Request #012-94 was filed with the
- * USA State Department, who handed it to the Commerce department. The
- * code was determined to fall under General License GTDA under ECCN 5D96G,
- * and hence exportable. The cryptographic interfaces were re-added by Eric
- * Young, and then KTH proceeded to maintain the code in the free world.
- *
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America is assumed
- * to require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-/* "$KTH: auth.c,v 1.23 2000/01/18 03:09:34 assar Exp $" */
-
-#if defined(AUTHENTICATION)
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <signal.h>
-#define AUTH_NAMES
-#include <arpa/telnet.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "encrypt.h"
-#include "auth.h"
-#include "misc-proto.h"
-#include "auth-proto.h"
-
-#define typemask(x) (1<<((x)-1))
-
-#ifdef KRB4_ENCPWD
-extern krb4encpwd_init();
-extern krb4encpwd_send();
-extern krb4encpwd_is();
-extern krb4encpwd_reply();
-extern krb4encpwd_status();
-extern krb4encpwd_printsub();
-#endif
-
-#ifdef RSA_ENCPWD
-extern rsaencpwd_init();
-extern rsaencpwd_send();
-extern rsaencpwd_is();
-extern rsaencpwd_reply();
-extern rsaencpwd_status();
-extern rsaencpwd_printsub();
-#endif
-
-int auth_debug_mode = 0;
-int auth_has_failed = 0;
-int auth_enable_encrypt = 0;
-static const char *Name = "Noname";
-static int Server = 0;
-static Authenticator *authenticated = 0;
-static int authenticating = 0;
-static int validuser = 0;
-static unsigned char _auth_send_data[256];
-static unsigned char *auth_send_data;
-static int auth_send_cnt = 0;
-
-/*
- * Authentication types supported. Plese note that these are stored
- * in priority order, i.e. try the first one first.
- */
-Authenticator authenticators[] = {
-#ifdef UNSAFE
- { AUTHTYPE_UNSAFE, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
- unsafe_init,
- unsafe_send,
- unsafe_is,
- unsafe_reply,
- unsafe_status,
- unsafe_printsub },
-#endif
-#ifdef SRA
- { AUTHTYPE_SRA, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
- sra_init,
- sra_send,
- sra_is,
- sra_reply,
- sra_status,
- sra_printsub },
-#endif
-#ifdef SPX
- { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
- spx_init,
- spx_send,
- spx_is,
- spx_reply,
- spx_status,
- spx_printsub },
- { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
- spx_init,
- spx_send,
- spx_is,
- spx_reply,
- spx_status,
- spx_printsub },
-#endif
-#ifdef KRB5
- { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
- kerberos5_init,
- kerberos5_send_mutual,
- kerberos5_is,
- kerberos5_reply,
- kerberos5_status,
- kerberos5_printsub },
- { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
- kerberos5_init,
- kerberos5_send_oneway,
- kerberos5_is,
- kerberos5_reply,
- kerberos5_status,
- kerberos5_printsub },
-#endif
-#ifdef KRB4
- { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
- kerberos4_init,
- kerberos4_send_mutual,
- kerberos4_is,
- kerberos4_reply,
- kerberos4_status,
- kerberos4_printsub },
- { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
- kerberos4_init,
- kerberos4_send_oneway,
- kerberos4_is,
- kerberos4_reply,
- kerberos4_status,
- kerberos4_printsub },
-#endif
-#ifdef KRB4_ENCPWD
- { AUTHTYPE_KRB4_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
- krb4encpwd_init,
- krb4encpwd_send,
- krb4encpwd_is,
- krb4encpwd_reply,
- krb4encpwd_status,
- krb4encpwd_printsub },
-#endif
-#ifdef RSA_ENCPWD
- { AUTHTYPE_RSA_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
- rsaencpwd_init,
- rsaencpwd_send,
- rsaencpwd_is,
- rsaencpwd_reply,
- rsaencpwd_status,
- rsaencpwd_printsub },
-#endif
- { 0, },
-};
-
-static Authenticator NoAuth = { 0 };
-
-static int i_support = 0;
-static int i_wont_support = 0;
-
-Authenticator *
-findauthenticator(int type, int way)
-{
- Authenticator *ap = authenticators;
-
- while (ap->type && (ap->type != type || ap->way != way))
- ++ap;
- return(ap->type ? ap : 0);
-}
-
-void
-auth_init(const char *name, int server)
-{
- Authenticator *ap = authenticators;
-
- Server = server;
- Name = name;
-
- i_support = 0;
- authenticated = 0;
- authenticating = 0;
- while (ap->type) {
- if (!ap->init || (*ap->init)(ap, server)) {
- i_support |= typemask(ap->type);
- if (auth_debug_mode)
- printf(">>>%s: I support auth type %d %d\r\n",
- Name,
- ap->type, ap->way);
- }
- else if (auth_debug_mode)
- printf(">>>%s: Init failed: auth type %d %d\r\n",
- Name, ap->type, ap->way);
- ++ap;
- }
-}
-
-void
-auth_disable_name(char *name)
-{
- int x;
- for (x = 0; x < AUTHTYPE_CNT; ++x) {
- if (!strcasecmp(name, AUTHTYPE_NAME(x))) {
- i_wont_support |= typemask(x);
- break;
- }
- }
-}
-
-int
-getauthmask(char *type, int *maskp)
-{
- int x;
-
- if (!strcasecmp(type, AUTHTYPE_NAME(0))) {
- *maskp = -1;
- return(1);
- }
-
- for (x = 1; x < AUTHTYPE_CNT; ++x) {
- if (!strcasecmp(type, AUTHTYPE_NAME(x))) {
- *maskp = typemask(x);
- return(1);
- }
- }
- return(0);
-}
-
-int
-auth_enable(char *type)
-{
- return(auth_onoff(type, 1));
-}
-
-int
-auth_disable(char *type)
-{
- return(auth_onoff(type, 0));
-}
-
-int
-auth_onoff(char *type, int on)
-{
- int i, mask = -1;
- Authenticator *ap;
-
- if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) {
- printf("auth %s 'type'\n", on ? "enable" : "disable");
- printf("Where 'type' is one of:\n");
- printf("\t%s\n", AUTHTYPE_NAME(0));
- mask = 0;
- for (ap = authenticators; ap->type; ap++) {
- if ((mask & (i = typemask(ap->type))) != 0)
- continue;
- mask |= i;
- printf("\t%s\n", AUTHTYPE_NAME(ap->type));
- }
- return(0);
- }
-
- if (!getauthmask(type, &mask)) {
- printf("%s: invalid authentication type\n", type);
- return(0);
- }
- if (on)
- i_wont_support &= ~mask;
- else
- i_wont_support |= mask;
- return(1);
-}
-
-int
-auth_togdebug(int on)
-{
- if (on < 0)
- auth_debug_mode ^= 1;
- else
- auth_debug_mode = on;
- printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled");
- return(1);
-}
-
-int
-auth_status(void)
-{
- Authenticator *ap;
- int i, mask;
-
- if (i_wont_support == -1)
- printf("Authentication disabled\n");
- else
- printf("Authentication enabled\n");
-
- mask = 0;
- for (ap = authenticators; ap->type; ap++) {
- if ((mask & (i = typemask(ap->type))) != 0)
- continue;
- mask |= i;
- printf("%s: %s\n", AUTHTYPE_NAME(ap->type),
- (i_wont_support & typemask(ap->type)) ?
- "disabled" : "enabled");
- }
- return(1);
-}
-
-/*
- * This routine is called by the server to start authentication
- * negotiation.
- */
-void
-auth_request(void)
-{
- static unsigned char str_request[64] = { IAC, SB,
- TELOPT_AUTHENTICATION,
- TELQUAL_SEND, };
- Authenticator *ap = authenticators;
- unsigned char *e = str_request + 4;
-
- if (!authenticating) {
- authenticating = 1;
- while (ap->type) {
- if (i_support & ~i_wont_support & typemask(ap->type)) {
- if (auth_debug_mode) {
- printf(">>>%s: Sending type %d %d\r\n",
- Name, ap->type, ap->way);
- }
- *e++ = ap->type;
- *e++ = ap->way;
- }
- ++ap;
- }
- *e++ = IAC;
- *e++ = SE;
- telnet_net_write(str_request, e - str_request);
- printsub('>', &str_request[2], e - str_request - 2);
- }
-}
-
-/*
- * This is called when an AUTH SEND is received.
- * It should never arrive on the server side (as only the server can
- * send an AUTH SEND).
- * You should probably respond to it if you can...
- *
- * If you want to respond to the types out of order (i.e. even
- * if he sends LOGIN KERBEROS and you support both, you respond
- * with KERBEROS instead of LOGIN (which is against what the
- * protocol says)) you will have to hack this code...
- */
-void
-auth_send(unsigned char *data, int cnt)
-{
- Authenticator *ap;
- static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION,
- TELQUAL_IS, AUTHTYPE_NULL, 0,
- IAC, SE };
- if (Server) {
- if (auth_debug_mode) {
- printf(">>>%s: auth_send called!\r\n", Name);
- }
- return;
- }
-
- if (auth_debug_mode) {
- printf(">>>%s: auth_send got:", Name);
- printd(data, cnt); printf("\r\n");
- }
-
- /*
- * Save the data, if it is new, so that we can continue looking
- * at it if the authorization we try doesn't work
- */
- if (data < _auth_send_data ||
- data > _auth_send_data + sizeof(_auth_send_data)) {
- auth_send_cnt = cnt > sizeof(_auth_send_data)
- ? sizeof(_auth_send_data)
- : cnt;
- memmove(_auth_send_data, data, auth_send_cnt);
- auth_send_data = _auth_send_data;
- } else {
- /*
- * This is probably a no-op, but we just make sure
- */
- auth_send_data = data;
- auth_send_cnt = cnt;
- }
- while ((auth_send_cnt -= 2) >= 0) {
- if (auth_debug_mode)
- printf(">>>%s: He supports %d\r\n",
- Name, *auth_send_data);
- if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) {
- ap = findauthenticator(auth_send_data[0],
- auth_send_data[1]);
- if (ap && ap->send) {
- if (auth_debug_mode)
- printf(">>>%s: Trying %d %d\r\n",
- Name, auth_send_data[0],
- auth_send_data[1]);
- if ((*ap->send)(ap)) {
- /*
- * Okay, we found one we like
- * and did it.
- * we can go home now.
- */
- if (auth_debug_mode)
- printf(">>>%s: Using type %d\r\n",
- Name, *auth_send_data);
- auth_send_data += 2;
- return;
- }
- }
- /* else
- * just continue on and look for the
- * next one if we didn't do anything.
- */
- }
- auth_send_data += 2;
- }
- telnet_net_write(str_none, sizeof(str_none));
- printsub('>', &str_none[2], sizeof(str_none) - 2);
- if (auth_debug_mode)
- printf(">>>%s: Sent failure message\r\n", Name);
- auth_finished(0, AUTH_REJECT);
- auth_has_failed = 1;
-#ifdef KANNAN
- /*
- * We requested strong authentication, however no mechanisms worked.
- * Therefore, exit on client end.
- */
- printf("Unable to securely authenticate user ... exit\n");
- exit(0);
-#endif /* KANNAN */
-}
-
-void
-auth_send_retry(void)
-{
- /*
- * if auth_send_cnt <= 0 then auth_send will end up rejecting
- * the authentication and informing the other side of this.
- */
- auth_send(auth_send_data, auth_send_cnt);
-}
-
-void
-auth_is(unsigned char *data, int cnt)
-{
- Authenticator *ap;
-
- if (cnt < 2)
- return;
-
- if (data[0] == AUTHTYPE_NULL) {
- auth_finished(0, AUTH_REJECT);
- return;
- }
-
- if ((ap = findauthenticator(data[0], data[1]))) {
- if (ap->is)
- (*ap->is)(ap, data+2, cnt-2);
- } else if (auth_debug_mode)
- printf(">>>%s: Invalid authentication in IS: %d\r\n",
- Name, *data);
-}
-
-void
-auth_reply(unsigned char *data, int cnt)
-{
- Authenticator *ap;
-
- if (cnt < 2)
- return;
-
- if ((ap = findauthenticator(data[0], data[1]))) {
- if (ap->reply)
- (*ap->reply)(ap, data+2, cnt-2);
- } else if (auth_debug_mode)
- printf(">>>%s: Invalid authentication in SEND: %d\r\n",
- Name, *data);
-}
-
-void
-auth_name(unsigned char *data, int cnt)
-{
- char savename[256];
-
- if (cnt < 1) {
- if (auth_debug_mode)
- printf(">>>%s: Empty name in NAME\r\n", Name);
- return;
- }
- if (cnt > sizeof(savename) - 1) {
- if (auth_debug_mode)
- printf(">>>%s: Name in NAME (%d) exceeds %lu length\r\n",
- Name, cnt, (unsigned long)(sizeof(savename)-1));
- return;
- }
- memmove(savename, data, cnt);
- savename[cnt] = '\0'; /* Null terminate */
- if (auth_debug_mode)
- printf(">>>%s: Got NAME [%s]\r\n", Name, savename);
- auth_encrypt_user(savename);
-}
-
-int
-auth_sendname(unsigned char *cp, int len)
-{
- static unsigned char str_request[256+6]
- = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, };
- unsigned char *e = str_request + 4;
- unsigned char *ee = &str_request[sizeof(str_request)-2];
-
- while (--len >= 0) {
- if ((*e++ = *cp++) == IAC)
- *e++ = IAC;
- if (e >= ee)
- return(0);
- }
- *e++ = IAC;
- *e++ = SE;
- telnet_net_write(str_request, e - str_request);
- printsub('>', &str_request[2], e - &str_request[2]);
- return(1);
-}
-
-void
-auth_finished(Authenticator *ap, int result)
-{
- if (!(authenticated = ap))
- authenticated = &NoAuth;
- validuser = result;
-}
-
-/* ARGSUSED */
-static void
-auth_intr(int sig)
-{
- auth_finished(0, AUTH_REJECT);
-}
-
-int
-auth_wait(char *name, size_t name_sz)
-{
- if (auth_debug_mode)
- printf(">>>%s: in auth_wait.\r\n", Name);
-
- if (Server && !authenticating)
- return(0);
-
- signal(SIGALRM, auth_intr);
- alarm(30);
- while (!authenticated)
- if (telnet_spin())
- break;
- alarm(0);
- signal(SIGALRM, SIG_DFL);
-
- /*
- * Now check to see if the user is valid or not
- */
- if (!authenticated || authenticated == &NoAuth)
- return(AUTH_REJECT);
-
- if (validuser == AUTH_VALID)
- validuser = AUTH_USER;
-
- if (authenticated->status)
- validuser = (*authenticated->status)(authenticated,
- name, name_sz,
- validuser);
- return(validuser);
-}
-
-void
-auth_debug(int mode)
-{
- auth_debug_mode = mode;
-}
-
-void
-auth_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
-{
- Authenticator *ap;
-
- if ((ap = findauthenticator(data[1], data[2])) && ap->printsub)
- (*ap->printsub)(data, cnt, buf, buflen);
- else
- auth_gen_printsub(data, cnt, buf, buflen);
-}
-
-void
-auth_gen_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
-{
- unsigned char *cp;
- unsigned char tbuf[16];
-
- cnt -= 3;
- data += 3;
- buf[buflen-1] = '\0';
- buf[buflen-2] = '*';
- buflen -= 2;
- for (; cnt > 0; cnt--, data++) {
- snprintf(tbuf, sizeof(tbuf), " %d", *data);
- for (cp = tbuf; *cp && buflen > 0; --buflen)
- *buf++ = *cp++;
- if (buflen <= 0)
- return;
- }
- *buf = '\0';
-}
-#endif
diff --git a/libexec/telnetd/auth.h b/libexec/telnetd/auth.h
deleted file mode 100644
index 888e4e9a407..00000000000
--- a/libexec/telnetd/auth.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*-
- * 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.
- *
- * from: @(#)auth.h 8.1 (Berkeley) 6/4/93
- * $OpenBSD: auth.h,v 1.2 2003/06/02 19:38:24 millert Exp $
- * $NetBSD: auth.h,v 1.5 1996/02/24 01:15:18 jtk Exp $
- */
-
-/*
- * This source code is no longer held under any constraint of USA
- * `cryptographic laws' since it was exported legally. The cryptographic
- * functions were removed from the code and a "Bones" distribution was
- * made. A Commodity Jurisdiction Request #012-94 was filed with the
- * USA State Department, who handed it to the Commerce department. The
- * code was determined to fall under General License GTDA under ECCN 5D96G,
- * and hence exportable. The cryptographic interfaces were re-added by Eric
- * Young, and then KTH proceeded to maintain the code in the free world.
- *
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America is assumed
- * to require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-/* $KTH: auth.h,v 1.4 1998/06/09 19:24:41 joda Exp $ */
-
-#ifndef __AUTH__
-#define __AUTH__
-
-#define AUTH_REJECT 0 /* Rejected */
-#define AUTH_UNKNOWN 1 /* We don't know who he is, but he's okay */
-#define AUTH_OTHER 2 /* We know him, but not his name */
-#define AUTH_USER 3 /* We know he name */
-#define AUTH_VALID 4 /* We know him, and he needs no password */
-
-typedef struct XauthP {
- int type;
- int way;
- int (*init) (struct XauthP *, int);
- int (*send) (struct XauthP *);
- void (*is) (struct XauthP *, unsigned char *, int);
- void (*reply) (struct XauthP *, unsigned char *, int);
- int (*status) (struct XauthP *, char *, size_t, int);
- void (*printsub) (unsigned char *, int, unsigned char *, int);
-} Authenticator;
-
-#include "auth-proto.h"
-
-extern int auth_debug_mode;
-#endif
diff --git a/libexec/telnetd/authenc.c b/libexec/telnetd/authenc.c
deleted file mode 100644
index 3e91789e34d..00000000000
--- a/libexec/telnetd/authenc.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*-
- * 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 "telnetd.h"
-
-/* RCSID("$KTH: authenc.c,v 1.10 2000/11/15 23:20:43 assar Exp $"); */
-
-int
-telnet_net_write(unsigned char *str, int len)
-{
- if (nfrontp + len < netobuf + BUFSIZ) {
- memmove(nfrontp, str, len);
- nfrontp += len;
- return(len);
- }
- return(0);
-}
-
-#ifdef AUTHENTICATION
-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
-}
-
-int
-telnet_spin(void)
-{
- return ttloop();
-}
-
-char *
-telnet_getenv(const char *val)
-{
- return(getenv(val));
-}
-
-char *
-telnet_gets(char *prompt, char *result, int length, int echo)
-{
- return NULL;
-}
-#endif
diff --git a/libexec/telnetd/defs.h b/libexec/telnetd/defs.h
deleted file mode 100644
index db312be384a..00000000000
--- a/libexec/telnetd/defs.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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.
- *
- * @(#)defs.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * Telnet server defines
- */
-
-#ifndef __DEFS_H__
-#define __DEFS_H__
-
-#if defined(PRINTOPTIONS) && defined(DIAGNOSTICS)
-#define TELOPTS
-#define TELCMDS
-#define SLC_NAMES
-#endif
-
-#if !defined(TIOCSCTTY) && defined(TCSETCTTY)
-# define TIOCSCTTY TCSETCTTY
-#endif
-
-#ifndef TIOCPKT_FLUSHWRITE
-#define TIOCPKT_FLUSHWRITE 0x02
-#endif
-
-#ifndef TIOCPKT_NOSTOP
-#define TIOCPKT_NOSTOP 0x10
-#endif
-
-#ifndef TIOCPKT_DOSTOP
-#define TIOCPKT_DOSTOP 0x20
-#endif
-
-/*
- * I/O data buffers defines
- */
-#define NETSLOP 4096
-#ifdef _CRAY
-#undef BUFSIZ
-#define BUFSIZ 2048
-#endif
-
-#define NIACCUM(c) { *netip++ = c; \
- ncc++; \
- }
-
-/* clock manipulations */
-#define settimer(x) (clocks.x = ++clocks.system)
-#define sequenceIs(x,y) (clocks.x < clocks.y)
-
-/*
- * 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
-
-#endif /* __DEFS_H__ */
diff --git a/libexec/telnetd/enc-proto.h b/libexec/telnetd/enc-proto.h
deleted file mode 100644
index 586e236ea78..00000000000
--- a/libexec/telnetd/enc-proto.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*-
- * 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.
- *
- * @(#)enc-proto.h 8.1 (Berkeley) 6/4/93
- *
- * @(#)enc-proto.h 5.2 (Berkeley) 3/22/91
- */
-
- /*
- * This source code is no longer held under any constraint of USA
- * `cryptographic laws' since it was exported legally. The cryptographic
- * functions were removed from the code and a "Bones" distribution was
- * made. A Commodity Jurisdiction Request #012-94 was filed with the
- * USA State Department, who handed it to the Commerce department. The
- * code was determined to fall under General License GTDA under ECCN 5D96G,
- * and hence exportable. The cryptographic interfaces were re-added by Eric
- * Young, and then KTH proceeded to maintain the code in the free world.
- *
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America is assumed
- * to require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-/* $KTH: enc-proto.h,v 1.10.8.1 2002/02/06 03:38:05 assar Exp $ */
-
-#if defined(ENCRYPTION)
-Encryptions *findencryption (int);
-Encryptions *finddecryption(int);
-int EncryptAutoDec(int);
-int EncryptAutoEnc(int);
-int EncryptDebug(int);
-int EncryptDisable(char*, char*);
-int EncryptEnable(char*, char*);
-int EncryptStart(char*);
-int EncryptStartInput(void);
-int EncryptStartOutput(void);
-int EncryptStatus(void);
-int EncryptStop(char*);
-int EncryptStopInput(void);
-int EncryptStopOutput(void);
-int EncryptType(char*, char*);
-int EncryptVerbose(int);
-void decrypt_auto(int);
-void encrypt_auto(int);
-void encrypt_debug(int);
-void encrypt_dec_keyid(unsigned char*, int);
-void encrypt_display(void);
-void encrypt_enc_keyid(unsigned char*, int);
-void encrypt_end(void);
-void encrypt_gen_printsub(unsigned char*, int, unsigned char*, int);
-void encrypt_init(const char*, int);
-void encrypt_is(unsigned char*, int);
-void encrypt_list_types(void);
-void encrypt_not(void);
-void encrypt_printsub(unsigned char*, int, unsigned char*, int);
-void encrypt_reply(unsigned char*, int);
-void encrypt_request_end(void);
-void encrypt_request_start(unsigned char*, int);
-void encrypt_send_end(void);
-void encrypt_send_keyid(int, unsigned char*, int, int);
-void encrypt_send_request_end(void);
-int encrypt_is_encrypting(void);
-void encrypt_send_request_start(void);
-void encrypt_send_support(void);
-void encrypt_session_key(Session_Key*, int);
-void encrypt_start(unsigned char*, int);
-void encrypt_start_output(int);
-void encrypt_support(unsigned char*, int);
-void encrypt_verbose_quiet(int);
-void encrypt_wait(void);
-int encrypt_delay(void);
-
-#ifdef TELENTD
-void encrypt_wait (void);
-#else
-void encrypt_display (void);
-#endif
-
-void cfb64_encrypt (unsigned char *, int);
-int cfb64_decrypt (int);
-void cfb64_init (int);
-int cfb64_start (int, int);
-int cfb64_is (unsigned char *, int);
-int cfb64_reply (unsigned char *, int);
-void cfb64_session (Session_Key *, int);
-int cfb64_keyid (int, unsigned char *, int *);
-void cfb64_printsub (unsigned char *, int, unsigned char *, int);
-
-void ofb64_encrypt (unsigned char *, int);
-int ofb64_decrypt (int);
-void ofb64_init (int);
-int ofb64_start (int, int);
-int ofb64_is (unsigned char *, int);
-int ofb64_reply (unsigned char *, int);
-void ofb64_session (Session_Key *, int);
-int ofb64_keyid (int, unsigned char *, int *);
-void ofb64_printsub (unsigned char *, int, unsigned char *, int);
-
-#endif
-
-#ifdef KRB4
-int check_krb4_tickets();
-#else
-#define check_krb4_tickets() 0
-#endif
-
-#ifdef KRB5
-int check_krb5_tickets();
-#else
-#define check_krb5_tickets() 0
-#endif
diff --git a/libexec/telnetd/enc_des.c b/libexec/telnetd/enc_des.c
deleted file mode 100644
index 8919d4b91a3..00000000000
--- a/libexec/telnetd/enc_des.c
+++ /dev/null
@@ -1,660 +0,0 @@
-/* $OpenBSD: enc_des.c,v 1.2 2003/06/02 19:38:25 millert 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.
- */
-
-/* $KTH: enc_des.c,v 1.16 1998/07/09 23:16:23 assar Exp $ */
-
-#if defined(AUTHENTICATION) && defined(ENCRYPTION) && defined(DES_ENCRYPTION)
-#include <arpa/telnet.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "encrypt.h"
-#include "misc-proto.h"
-#include <des.h>
-
-extern int encrypt_debug_mode;
-
-#define CFB 0
-#define OFB 1
-
-#define NO_SEND_IV 1
-#define NO_RECV_IV 2
-#define NO_KEYID 4
-#define IN_PROGRESS (NO_SEND_IV|NO_RECV_IV|NO_KEYID)
-#define SUCCESS 0
-#define FAILED -1
-
-
-struct stinfo {
- des_cblock str_output;
- des_cblock str_feed;
- des_cblock str_iv;
- des_cblock str_ikey;
- des_key_schedule str_sched;
- int str_index;
- int str_flagshift;
-};
-
-struct fb {
- des_cblock krbdes_key;
- des_key_schedule krbdes_sched;
- des_cblock temp_feed;
- unsigned char fb_feed[64];
- int need_start;
- int state[2];
- int keyid[2];
- int once;
- struct stinfo streams[2];
-};
-
-static struct fb fb[2];
-
-struct keyidlist {
- char *keyid;
- int keyidlen;
- char *key;
- int keylen;
- int flags;
-} keyidlist [] = {
- { "\0", 1, 0, 0, 0 }, /* default key of zero */
- { 0, 0, 0, 0, 0 }
-};
-
-#define KEYFLAG_MASK 03
-
-#define KEYFLAG_NOINIT 00
-#define KEYFLAG_INIT 01
-#define KEYFLAG_OK 02
-#define KEYFLAG_BAD 03
-
-#define KEYFLAG_SHIFT 2
-
-#define SHIFT_VAL(a,b) (KEYFLAG_SHIFT*((a)+((b)*2)))
-
-#define FB64_IV 1
-#define FB64_IV_OK 2
-#define FB64_IV_BAD 3
-
-
-void fb64_stream_iv (des_cblock, struct stinfo *);
-void fb64_init (struct fb *);
-static int fb64_start (struct fb *, int, int);
-int fb64_is (unsigned char *, int, struct fb *);
-int fb64_reply (unsigned char *, int, struct fb *);
-static void fb64_session (Session_Key *, int, struct fb *);
-void fb64_stream_key (des_cblock, struct stinfo *);
-int fb64_keyid (int, unsigned char *, int *, struct fb *);
-
-void cfb64_init(int server)
-{
- fb64_init(&fb[CFB]);
- fb[CFB].fb_feed[4] = ENCTYPE_DES_CFB64;
- fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB);
- fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB);
-}
-
-
-void ofb64_init(int server)
-{
- fb64_init(&fb[OFB]);
- fb[OFB].fb_feed[4] = ENCTYPE_DES_OFB64;
- fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB);
- fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB);
-}
-
-void fb64_init(struct fb *fbp)
-{
- memset(fbp,0, sizeof(*fbp));
- fbp->state[0] = fbp->state[1] = FAILED;
- fbp->fb_feed[0] = IAC;
- fbp->fb_feed[1] = SB;
- fbp->fb_feed[2] = TELOPT_ENCRYPT;
- fbp->fb_feed[3] = ENCRYPT_IS;
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- * 2: Not yet. Other things (like getting the key from
- * Kerberos) have to happen before we can continue.
- */
-int cfb64_start(int dir, int server)
-{
- return(fb64_start(&fb[CFB], dir, server));
-}
-
-int ofb64_start(int dir, int server)
-{
- return(fb64_start(&fb[OFB], dir, server));
-}
-
-static int fb64_start(struct fb *fbp, int dir, int server)
-{
- int x;
- unsigned char *p;
- int state;
-
- switch (dir) {
- case DIR_DECRYPT:
- /*
- * This is simply a request to have the other side
- * start output (our input). He will negotiate an
- * IV so we need not look for it.
- */
- state = fbp->state[dir-1];
- if (state == FAILED)
- state = IN_PROGRESS;
- break;
-
- case DIR_ENCRYPT:
- state = fbp->state[dir-1];
- if (state == FAILED)
- state = IN_PROGRESS;
- else if ((state & NO_SEND_IV) == 0) {
- break;
- }
-
- if (!VALIDKEY(fbp->krbdes_key)) {
- fbp->need_start = 1;
- break;
- }
-
- state &= ~NO_SEND_IV;
- state |= NO_RECV_IV;
- if (encrypt_debug_mode)
- printf("Creating new feed\r\n");
- /*
- * Create a random feed and send it over.
- */
-#ifndef OLD_DES_RANDOM_KEY
- des_new_random_key(&fbp->temp_feed);
-#else
- /*
- * From des_cryp.man "If the des_check_key flag is non-zero,
- * des_set_key will check that the key passed is
- * of odd parity and is not a week or semi-weak key."
- */
- do {
- des_random_key(fbp->temp_feed);
- des_set_odd_parity(fbp->temp_feed);
- } while (des_is_weak_key(fbp->temp_feed));
-#endif
- des_ecb_encrypt(&fbp->temp_feed,
- &fbp->temp_feed,
- fbp->krbdes_sched, 1);
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_IS;
- p++;
- *p++ = FB64_IV;
- for (x = 0; x < sizeof(des_cblock); ++x) {
- if ((*p++ = fbp->temp_feed[x]) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]);
- telnet_net_write(fbp->fb_feed, p - fbp->fb_feed);
- break;
- default:
- return(FAILED);
- }
- return(fbp->state[dir-1] = state);
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- */
-
-int cfb64_is(unsigned char *data, int cnt)
-{
- return(fb64_is(data, cnt, &fb[CFB]));
-}
-
-int ofb64_is(unsigned char *data, int cnt)
-{
- return(fb64_is(data, cnt, &fb[OFB]));
-}
-
-
-int fb64_is(unsigned char *data, int cnt, struct fb *fbp)
-{
- unsigned char *p;
- int state = fbp->state[DIR_DECRYPT-1];
-
- if (cnt-- < 1)
- goto failure;
-
- switch (*data++) {
- case FB64_IV:
- if (cnt != sizeof(des_cblock)) {
- if (encrypt_debug_mode)
- printf("CFB64: initial vector failed on size\r\n");
- state = FAILED;
- goto failure;
- }
-
- if (encrypt_debug_mode)
- printf("CFB64: initial vector received\r\n");
-
- if (encrypt_debug_mode)
- printf("Initializing Decrypt stream\r\n");
-
- fb64_stream_iv(data, &fbp->streams[DIR_DECRYPT-1]);
-
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_REPLY;
- p++;
- *p++ = FB64_IV_OK;
- *p++ = IAC;
- *p++ = SE;
- printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]);
- telnet_net_write(fbp->fb_feed, p - fbp->fb_feed);
-
- state = fbp->state[DIR_DECRYPT-1] = IN_PROGRESS;
- break;
-
- default:
- if (encrypt_debug_mode) {
- printf("Unknown option type: %d\r\n", *(data-1));
- printd(data, cnt);
- printf("\r\n");
- }
- /* FALL THROUGH */
- failure:
- /*
- * We failed. Send an FB64_IV_BAD option
- * to the other side so it will know that
- * things failed.
- */
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_REPLY;
- p++;
- *p++ = FB64_IV_BAD;
- *p++ = IAC;
- *p++ = SE;
- printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]);
- telnet_net_write(fbp->fb_feed, p - fbp->fb_feed);
-
- break;
- }
- return(fbp->state[DIR_DECRYPT-1] = state);
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- */
-
-int cfb64_reply(unsigned char *data, int cnt)
-{
- return(fb64_reply(data, cnt, &fb[CFB]));
-}
-
-int ofb64_reply(unsigned char *data, int cnt)
-{
- return(fb64_reply(data, cnt, &fb[OFB]));
-}
-
-
-int fb64_reply(unsigned char *data, int cnt, struct fb *fbp)
-{
- int state = fbp->state[DIR_ENCRYPT-1];
-
- if (cnt-- < 1)
- goto failure;
-
- switch (*data++) {
- case FB64_IV_OK:
- fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
- if (state == FAILED)
- state = IN_PROGRESS;
- state &= ~NO_RECV_IV;
- encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1);
- break;
-
- case FB64_IV_BAD:
- memset(fbp->temp_feed, 0, sizeof(des_cblock));
- fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
- state = FAILED;
- break;
-
- default:
- if (encrypt_debug_mode) {
- printf("Unknown option type: %d\r\n", data[-1]);
- printd(data, cnt);
- printf("\r\n");
- }
- /* FALL THROUGH */
- failure:
- state = FAILED;
- break;
- }
- return(fbp->state[DIR_ENCRYPT-1] = state);
-}
-
-void cfb64_session(Session_Key *key, int server)
-{
- fb64_session(key, server, &fb[CFB]);
-}
-
-void ofb64_session(Session_Key *key, int server)
-{
- fb64_session(key, server, &fb[OFB]);
-}
-
-static void fb64_session(Session_Key *key, int server, struct fb *fbp)
-{
-
- if (!key || key->type != SK_DES) {
- if (encrypt_debug_mode)
- printf("Can't set krbdes's session key (%d != %d)\r\n",
- key ? key->type : -1, SK_DES);
- return;
- }
- memcpy(fbp->krbdes_key, key->data, sizeof(des_cblock));
-
- fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_ENCRYPT-1]);
- fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_DECRYPT-1]);
-
- if (fbp->once == 0) {
-#ifndef OLD_DES_RANDOM_KEY
- des_init_random_number_generator(&fbp->krbdes_key);
-#endif
- fbp->once = 1;
- }
- des_key_sched(&fbp->krbdes_key, fbp->krbdes_sched);
- /*
- * Now look to see if krbdes_start() was was waiting for
- * the key to show up. If so, go ahead an call it now
- * that we have the key.
- */
- if (fbp->need_start) {
- fbp->need_start = 0;
- fb64_start(fbp, DIR_ENCRYPT, server);
- }
-}
-
-/*
- * We only accept a keyid of 0. If we get a keyid of
- * 0, then mark the state as SUCCESS.
- */
-
-int cfb64_keyid(int dir, unsigned char *kp, int *lenp)
-{
- return(fb64_keyid(dir, kp, lenp, &fb[CFB]));
-}
-
-int ofb64_keyid(int dir, unsigned char *kp, int *lenp)
-{
- return(fb64_keyid(dir, kp, lenp, &fb[OFB]));
-}
-
-int fb64_keyid(int dir, unsigned char *kp, int *lenp, struct fb *fbp)
-{
- int state = fbp->state[dir-1];
-
- if (*lenp != 1 || (*kp != '\0')) {
- *lenp = 0;
- return(state);
- }
-
- if (state == FAILED)
- state = IN_PROGRESS;
-
- state &= ~NO_KEYID;
-
- return(fbp->state[dir-1] = state);
-}
-
-void fb64_printsub(unsigned char *data, int cnt,
- unsigned char *buf, int buflen, char *type)
-{
- char lbuf[32];
- int i;
- char *cp;
-
- buf[buflen-1] = '\0'; /* make sure it's NULL terminated */
- buflen -= 1;
-
- switch(data[2]) {
- case FB64_IV:
- snprintf(lbuf, sizeof(lbuf), "%s_IV", type);
- cp = lbuf;
- goto common;
-
- case FB64_IV_OK:
- snprintf(lbuf, sizeof(lbuf), "%s_IV_OK", type);
- cp = lbuf;
- goto common;
-
- case FB64_IV_BAD:
- snprintf(lbuf, sizeof(lbuf), "%s_IV_BAD", type);
- cp = lbuf;
- goto common;
-
- default:
- snprintf(lbuf, sizeof(lbuf), " %d (unknown)", data[2]);
- cp = lbuf;
- common:
- for (; (buflen > 0) && (*buf = *cp++); buf++)
- buflen--;
- for (i = 3; i < cnt; i++) {
- snprintf(lbuf, sizeof(lbuf), " %d", data[i]);
- for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++)
- buflen--;
- }
- break;
- }
-}
-
-void cfb64_printsub(unsigned char *data, int cnt,
- unsigned char *buf, int buflen)
-{
- fb64_printsub(data, cnt, buf, buflen, "CFB64");
-}
-
-void ofb64_printsub(unsigned char *data, int cnt,
- unsigned char *buf, int buflen)
-{
- fb64_printsub(data, cnt, buf, buflen, "OFB64");
-}
-
-void fb64_stream_iv(des_cblock seed, struct stinfo *stp)
-{
-
- memcpy(stp->str_iv, seed,sizeof(des_cblock));
- memcpy(stp->str_output, seed, sizeof(des_cblock));
-
- des_key_sched(&stp->str_ikey, stp->str_sched);
-
- stp->str_index = sizeof(des_cblock);
-}
-
-void fb64_stream_key(des_cblock key, struct stinfo *stp)
-{
- memcpy(stp->str_ikey, key, sizeof(des_cblock));
- des_key_sched((des_cblock*)key, stp->str_sched);
-
- memcpy(stp->str_output, stp->str_iv, sizeof(des_cblock));
-
- stp->str_index = sizeof(des_cblock);
-}
-
-/*
- * DES 64 bit Cipher Feedback
- *
- * key --->+-----+
- * +->| DES |--+
- * | +-----+ |
- * | v
- * INPUT --(--------->(+)+---> DATA
- * | |
- * +-------------+
- *
- *
- * Given:
- * iV: Initial vector, 64 bits (8 bytes) long.
- * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
- * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
- *
- * V0 = DES(iV, key)
- * On = Dn ^ Vn
- * V(n+1) = DES(On, key)
- */
-
-void cfb64_encrypt(unsigned char *s, int c)
-{
- struct stinfo *stp = &fb[CFB].streams[DIR_ENCRYPT-1];
- int index;
-
- index = stp->str_index;
- while (c-- > 0) {
- if (index == sizeof(des_cblock)) {
- des_cblock b;
- des_ecb_encrypt(&stp->str_output, &b,stp->str_sched, 1);
- memcpy(stp->str_feed, b, sizeof(des_cblock));
- index = 0;
- }
-
- /* On encryption, we store (feed ^ data) which is cypher */
- *s = stp->str_output[index] = (stp->str_feed[index] ^ *s);
- s++;
- index++;
- }
- stp->str_index = index;
-}
-
-int cfb64_decrypt(int data)
-{
- struct stinfo *stp = &fb[CFB].streams[DIR_DECRYPT-1];
- int index;
-
- if (data == -1) {
- /*
- * Back up one byte. It is assumed that we will
- * never back up more than one byte. If we do, this
- * may or may not work.
- */
- if (stp->str_index)
- --stp->str_index;
- return(0);
- }
-
- index = stp->str_index++;
- if (index == sizeof(des_cblock)) {
- des_cblock b;
- des_ecb_encrypt(&stp->str_output,&b, stp->str_sched, 1);
- memcpy(stp->str_feed, b, sizeof(des_cblock));
- stp->str_index = 1; /* Next time will be 1 */
- index = 0; /* But now use 0 */
- }
-
- /* On decryption we store (data) which is cypher. */
- stp->str_output[index] = data;
- return(data ^ stp->str_feed[index]);
-}
-
-/*
- * DES 64 bit Output Feedback
- *
- * key --->+-----+
- * +->| DES |--+
- * | +-----+ |
- * +-----------+
- * v
- * INPUT -------->(+) ----> DATA
- *
- * Given:
- * iV: Initial vector, 64 bits (8 bytes) long.
- * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
- * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
- *
- * V0 = DES(iV, key)
- * V(n+1) = DES(Vn, key)
- * On = Dn ^ Vn
- */
-
-void ofb64_encrypt(unsigned char *s, int c)
-{
- struct stinfo *stp = &fb[OFB].streams[DIR_ENCRYPT-1];
- int index;
-
- index = stp->str_index;
- while (c-- > 0) {
- if (index == sizeof(des_cblock)) {
- des_cblock b;
- des_ecb_encrypt(&stp->str_feed,&b, stp->str_sched, 1);
- memcpy(stp->str_feed, b, sizeof(des_cblock));
- index = 0;
- }
- *s++ ^= stp->str_feed[index];
- index++;
- }
- stp->str_index = index;
-}
-
-int ofb64_decrypt(int data)
-{
- struct stinfo *stp = &fb[OFB].streams[DIR_DECRYPT-1];
- int index;
-
- if (data == -1) {
- /*
- * Back up one byte. It is assumed that we will
- * never back up more than one byte. If we do, this
- * may or may not work.
- */
- if (stp->str_index)
- --stp->str_index;
- return(0);
- }
-
- index = stp->str_index++;
- if (index == sizeof(des_cblock)) {
- des_cblock b;
- des_ecb_encrypt(&stp->str_feed,&b,stp->str_sched, 1);
- memcpy(stp->str_feed, b, sizeof(des_cblock));
- stp->str_index = 1; /* Next time will be 1 */
- index = 0; /* But now use 0 */
- }
-
- return(data ^ stp->str_feed[index]);
-}
-#endif
-
diff --git a/libexec/telnetd/encrypt.c b/libexec/telnetd/encrypt.c
deleted file mode 100644
index 08a56f360f9..00000000000
--- a/libexec/telnetd/encrypt.c
+++ /dev/null
@@ -1,1005 +0,0 @@
-/* $OpenBSD: encrypt.c,v 1.3 2003/06/26 07:53:27 deraadt 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.
- */
-
- /*
- * This source code is no longer held under any constraint of USA
- * `cryptographic laws' since it was exported legally. The cryptographic
- * functions were removed from the code and a "Bones" distribution was
- * made. A Commodity Jurisdiction Request #012-94 was filed with the
- * USA State Department, who handed it to the Commerce department. The
- * code was determined to fall under General License GTDA under ECCN 5D96G,
- * and hence exportable. The cryptographic interfaces were re-added by Eric
- * Young, and then KTH proceeded to maintain the code in the free world.
- *
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America is assumed
- * to require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-/*
-RCSID("$KTH: encrypt.c,v 1.22.8.1 2002/02/06 03:39:13 assar Exp $");
-*/
-
-#if defined(ENCRYPTION)
-
-#define ENCRYPT_NAMES
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <arpa/telnet.h>
-
-#include "encrypt.h"
-#include "misc.h"
-
-
-
-/*
- * These functions pointers point to the current routines
- * for encrypting and decrypting data.
- */
-void (*encrypt_output) (unsigned char *, int);
-int (*decrypt_input) (int);
-char *nclearto;
-
-int encrypt_debug_mode = 0;
-static int decrypt_mode = 0;
-static int encrypt_mode = 0;
-static int encrypt_verbose = 0;
-static int autoencrypt = 0;
-static int autodecrypt = 0;
-static int havesessionkey = 0;
-static int Server = 0;
-static const char *Name = "Noname";
-
-#define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0)
-
-static long i_support_encrypt = typemask(ENCTYPE_DES_CFB64)
- | typemask(ENCTYPE_DES_OFB64);
- static long i_support_decrypt = typemask(ENCTYPE_DES_CFB64)
- | typemask(ENCTYPE_DES_OFB64);
- static long i_wont_support_encrypt = 0;
- static long i_wont_support_decrypt = 0;
-#define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt)
-#define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt)
-
- static long remote_supports_encrypt = 0;
- static long remote_supports_decrypt = 0;
-
- static Encryptions encryptions[] = {
-#if defined(DES_ENCRYPTION)
- { "DES_CFB64", ENCTYPE_DES_CFB64,
- cfb64_encrypt,
- cfb64_decrypt,
- cfb64_init,
- cfb64_start,
- cfb64_is,
- cfb64_reply,
- cfb64_session,
- cfb64_keyid,
- cfb64_printsub },
- { "DES_OFB64", ENCTYPE_DES_OFB64,
- ofb64_encrypt,
- ofb64_decrypt,
- ofb64_init,
- ofb64_start,
- ofb64_is,
- ofb64_reply,
- ofb64_session,
- ofb64_keyid,
- ofb64_printsub },
-#endif
- { 0, },
- };
-
-static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT,
- ENCRYPT_SUPPORT };
-static unsigned char str_suplen = 0;
-static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT };
-static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE };
-
-Encryptions *
-findencryption(int type)
-{
- Encryptions *ep = encryptions;
-
- if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & typemask(type)))
- return(0);
- while (ep->type && ep->type != type)
- ++ep;
- return(ep->type ? ep : 0);
-}
-
-Encryptions *
-finddecryption(int type)
-{
- Encryptions *ep = encryptions;
-
- if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & typemask(type)))
- return(0);
- while (ep->type && ep->type != type)
- ++ep;
- return(ep->type ? ep : 0);
-}
-
-#define MAXKEYLEN 64
-
-static struct key_info {
- unsigned char keyid[MAXKEYLEN];
- int keylen;
- int dir;
- int *modep;
- Encryptions *(*getcrypt)(int);
-} ki[2] = {
- { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption },
- { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption },
-};
-
-void
-encrypt_init(const char *name, int server)
-{
- Encryptions *ep = encryptions;
-
- Name = name;
- Server = server;
- i_support_encrypt = i_support_decrypt = 0;
- remote_supports_encrypt = remote_supports_decrypt = 0;
- encrypt_mode = 0;
- decrypt_mode = 0;
- encrypt_output = 0;
- decrypt_input = 0;
-#ifdef notdef
- encrypt_verbose = !server;
-#endif
-
- str_suplen = 4;
-
- while (ep->type) {
- if (encrypt_debug_mode)
- printf(">>>%s: I will support %s\r\n",
- Name, ENCTYPE_NAME(ep->type));
- i_support_encrypt |= typemask(ep->type);
- i_support_decrypt |= typemask(ep->type);
- if ((i_wont_support_decrypt & typemask(ep->type)) == 0)
- if ((str_send[str_suplen++] = ep->type) == IAC)
- str_send[str_suplen++] = IAC;
- if (ep->init)
- (*ep->init)(Server);
- ++ep;
- }
- str_send[str_suplen++] = IAC;
- str_send[str_suplen++] = SE;
-}
-
-void
-encrypt_list_types(void)
-{
- Encryptions *ep = encryptions;
-
- printf("Valid encryption types:\n");
- while (ep->type) {
- printf("\t%s (%d)\r\n", ENCTYPE_NAME(ep->type), ep->type);
- ++ep;
- }
-}
-
-int
-EncryptEnable(char *type, char *mode)
-{
- if (isprefix(type, "help") || isprefix(type, "?")) {
- printf("Usage: encrypt enable <type> [input|output]\n");
- encrypt_list_types();
- return(0);
- }
- if (EncryptType(type, mode))
- return(EncryptStart(mode));
- return(0);
-}
-
-int
-EncryptDisable(char *type, char *mode)
-{
- Encryptions *ep;
- int ret = 0;
-
- if (isprefix(type, "help") || isprefix(type, "?")) {
- printf("Usage: encrypt disable <type> [input|output]\n");
- encrypt_list_types();
- } else if ((ep = (Encryptions *)genget(type, (char**)encryptions,
- sizeof(Encryptions))) == 0) {
- printf("%s: invalid encryption type\n", type);
- } else if (Ambiguous(ep)) {
- printf("Ambiguous type '%s'\n", type);
- } else {
- if ((mode == 0) || (isprefix(mode, "input") ? 1 : 0)) {
- if (decrypt_mode == ep->type)
- EncryptStopInput();
- i_wont_support_decrypt |= typemask(ep->type);
- ret = 1;
- }
- if ((mode == 0) || (isprefix(mode, "output"))) {
- if (encrypt_mode == ep->type)
- EncryptStopOutput();
- i_wont_support_encrypt |= typemask(ep->type);
- ret = 1;
- }
- if (ret == 0)
- printf("%s: invalid encryption mode\n", mode);
- }
- return(ret);
-}
-
-int
-EncryptType(char *type, char *mode)
-{
- Encryptions *ep;
- int ret = 0;
-
- if (isprefix(type, "help") || isprefix(type, "?")) {
- printf("Usage: encrypt type <type> [input|output]\n");
- encrypt_list_types();
- } else if ((ep = (Encryptions *)genget(type, (char**)encryptions,
- sizeof(Encryptions))) == 0) {
- printf("%s: invalid encryption type\n", type);
- } else if (Ambiguous(ep)) {
- printf("Ambiguous type '%s'\n", type);
- } else {
- if ((mode == 0) || isprefix(mode, "input")) {
- decrypt_mode = ep->type;
- i_wont_support_decrypt &= ~typemask(ep->type);
- ret = 1;
- }
- if ((mode == 0) || isprefix(mode, "output")) {
- encrypt_mode = ep->type;
- i_wont_support_encrypt &= ~typemask(ep->type);
- ret = 1;
- }
- if (ret == 0)
- printf("%s: invalid encryption mode\n", mode);
- }
- return(ret);
-}
-
-int
-EncryptStart(char *mode)
-{
- int ret = 0;
- if (mode) {
- if (isprefix(mode, "input"))
- return(EncryptStartInput());
- if (isprefix(mode, "output"))
- return(EncryptStartOutput());
- if (isprefix(mode, "help") || isprefix(mode, "?")) {
- printf("Usage: encrypt start [input|output]\n");
- return(0);
- }
- printf("%s: invalid encryption mode 'encrypt start ?' for help\n", mode);
- return(0);
- }
- ret += EncryptStartInput();
- ret += EncryptStartOutput();
- return(ret);
-}
-
-int
-EncryptStartInput(void)
-{
- if (decrypt_mode) {
- encrypt_send_request_start();
- return(1);
- }
- printf("No previous decryption mode, decryption not enabled\r\n");
- return(0);
-}
-
-int
-EncryptStartOutput(void)
-{
- if (encrypt_mode) {
- encrypt_start_output(encrypt_mode);
- return(1);
- }
- printf("No previous encryption mode, encryption not enabled\r\n");
- return(0);
-}
-
-int
-EncryptStop(char *mode)
-{
- int ret = 0;
- if (mode) {
- if (isprefix(mode, "input"))
- return(EncryptStopInput());
- if (isprefix(mode, "output"))
- return(EncryptStopOutput());
- if (isprefix(mode, "help") || isprefix(mode, "?")) {
- printf("Usage: encrypt stop [input|output]\n");
- return(0);
- }
- printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode);
- return(0);
- }
- ret += EncryptStopInput();
- ret += EncryptStopOutput();
- return(ret);
-}
-
-int
-EncryptStopInput(void)
-{
- encrypt_send_request_end();
- return(1);
-}
-
-int
-EncryptStopOutput(void)
-{
- encrypt_send_end();
- return(1);
-}
-
-void
-encrypt_display(void)
-{
- printf("Autoencrypt for output is %s. Autodecrypt for input is %s.\r\n",
- autoencrypt?"on":"off", autodecrypt?"on":"off");
-
- if (encrypt_output)
- printf("Currently encrypting output with %s\r\n",
- ENCTYPE_NAME(encrypt_mode));
- else
- printf("Currently not encrypting output\r\n");
-
- if (decrypt_input)
- printf("Currently decrypting input with %s\r\n",
- ENCTYPE_NAME(decrypt_mode));
- else
- printf("Currently not decrypting input\r\n");
-}
-
-int
-EncryptStatus(void)
-{
- printf("Autoencrypt for output is %s. Autodecrypt for input is %s.\r\n",
- autoencrypt?"on":"off", autodecrypt?"on":"off");
-
- if (encrypt_output)
- printf("Currently encrypting output with %s\r\n",
- ENCTYPE_NAME(encrypt_mode));
- else if (encrypt_mode) {
- printf("Currently output is clear text.\r\n");
- printf("Last encryption mode was %s\r\n",
- ENCTYPE_NAME(encrypt_mode));
- } else
- printf("Currently not encrypting output\r\n");
-
- if (decrypt_input) {
- printf("Currently decrypting input with %s\r\n",
- ENCTYPE_NAME(decrypt_mode));
- } else if (decrypt_mode) {
- printf("Currently input is clear text.\r\n");
- printf("Last decryption mode was %s\r\n",
- ENCTYPE_NAME(decrypt_mode));
- } else
- printf("Currently not decrypting input\r\n");
-
- return 1;
-}
-
-void
-encrypt_send_support(void)
-{
- if (str_suplen) {
- /*
- * If the user has requested that decryption start
- * immediatly, then send a "REQUEST START" before
- * we negotiate the type.
- */
- if (!Server && autodecrypt)
- encrypt_send_request_start();
- telnet_net_write(str_send, str_suplen);
- printsub('>', &str_send[2], str_suplen - 2);
- str_suplen = 0;
- }
-}
-
-int
-EncryptDebug(int on)
-{
- if (on < 0)
- encrypt_debug_mode ^= 1;
- else
- encrypt_debug_mode = on;
- printf("Encryption debugging %s\r\n",
- encrypt_debug_mode ? "enabled" : "disabled");
- return(1);
-}
-
-/* turn on verbose encryption, but dont keep telling the whole world
- */
-void encrypt_verbose_quiet(int on)
-{
- if(on < 0)
- encrypt_verbose ^= 1;
- else
- encrypt_verbose = on ? 1 : 0;
-}
-
-int
-EncryptVerbose(int on)
-{
- encrypt_verbose_quiet(on);
- printf("Encryption %s verbose\r\n",
- encrypt_verbose ? "is" : "is not");
- return(1);
-}
-
-int
-EncryptAutoEnc(int on)
-{
- encrypt_auto(on);
- printf("Automatic encryption of output is %s\r\n",
- autoencrypt ? "enabled" : "disabled");
- return(1);
-}
-
-int
-EncryptAutoDec(int on)
-{
- decrypt_auto(on);
- printf("Automatic decryption of input is %s\r\n",
- autodecrypt ? "enabled" : "disabled");
- return(1);
-}
-
-/* Called when we receive a WONT or a DONT ENCRYPT after we sent a DO
- encrypt */
-void
-encrypt_not(void)
-{
- if (encrypt_verbose)
- printf("[ Connection is NOT encrypted ]\r\n");
-}
-
-/*
- * Called when ENCRYPT SUPPORT is received.
- */
-void
-encrypt_support(unsigned char *typelist, int cnt)
-{
- int type, use_type = 0;
- Encryptions *ep;
-
- /*
- * Forget anything the other side has previously told us.
- */
- remote_supports_decrypt = 0;
-
- while (cnt-- > 0) {
- type = *typelist++;
- if (encrypt_debug_mode)
- printf(">>>%s: He is supporting %s (%d)\r\n",
- Name,
- ENCTYPE_NAME(type), type);
- if ((type < ENCTYPE_CNT) &&
- (I_SUPPORT_ENCRYPT & typemask(type))) {
- remote_supports_decrypt |= typemask(type);
- if (use_type == 0)
- use_type = type;
- }
- }
- if (use_type) {
- ep = findencryption(use_type);
- if (!ep)
- return;
- type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0;
- if (encrypt_debug_mode)
- printf(">>>%s: (*ep->start)() returned %d\r\n",
- Name, type);
- if (type < 0)
- return;
- encrypt_mode = use_type;
- if (type == 0)
- encrypt_start_output(use_type);
- }
-}
-
-void
-encrypt_is(unsigned char *data, int cnt)
-{
- Encryptions *ep;
- int type, ret;
-
- if (--cnt < 0)
- return;
- type = *data++;
- if (type < ENCTYPE_CNT)
- remote_supports_encrypt |= typemask(type);
- if (!(ep = finddecryption(type))) {
- if (encrypt_debug_mode)
- printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
- Name,
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type);
- return;
- }
- if (!ep->is) {
- if (encrypt_debug_mode)
- printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n",
- Name,
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type);
- ret = 0;
- } else {
- ret = (*ep->is)(data, cnt);
- if (encrypt_debug_mode)
- printf("(*ep->is)(%p, %d) returned %s(%d)\n", data, cnt,
- (ret < 0) ? "FAIL " :
- (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
- }
- if (ret < 0) {
- autodecrypt = 0;
- } else {
- decrypt_mode = type;
- if (ret == 0 && autodecrypt)
- encrypt_send_request_start();
- }
-}
-
-void
-encrypt_reply(unsigned char *data, int cnt)
-{
- Encryptions *ep;
- int ret, type;
-
- if (--cnt < 0)
- return;
- type = *data++;
- if (!(ep = findencryption(type))) {
- if (encrypt_debug_mode)
- printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
- Name,
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type);
- return;
- }
- if (!ep->reply) {
- if (encrypt_debug_mode)
- printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n",
- Name,
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type);
- ret = 0;
- } else {
- ret = (*ep->reply)(data, cnt);
- if (encrypt_debug_mode)
- printf("(*ep->reply)(%p, %d) returned %s(%d)\n",
- data, cnt,
- (ret < 0) ? "FAIL " :
- (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
- }
- if (encrypt_debug_mode)
- printf(">>>%s: encrypt_reply returned %d\n", Name, ret);
- if (ret < 0) {
- autoencrypt = 0;
- } else {
- encrypt_mode = type;
- if (ret == 0 && autoencrypt)
- encrypt_start_output(type);
- }
-}
-
-/*
- * Called when a ENCRYPT START command is received.
- */
-void
-encrypt_start(unsigned char *data, int cnt)
-{
- Encryptions *ep;
-
- if (!decrypt_mode) {
- /*
- * Something is wrong. We should not get a START
- * command without having already picked our
- * decryption scheme. Send a REQUEST-END to
- * attempt to clear the channel...
- */
- printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name);
- encrypt_send_request_end();
- return;
- }
-
- if ((ep = finddecryption(decrypt_mode))) {
- decrypt_input = ep->input;
- if (encrypt_verbose)
- printf("[ Input is now decrypted with type %s ]\r\n",
- ENCTYPE_NAME(decrypt_mode));
- if (encrypt_debug_mode)
- printf(">>>%s: Start to decrypt input with type %s\r\n",
- Name, ENCTYPE_NAME(decrypt_mode));
- } else {
- printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n",
- Name,
- ENCTYPE_NAME_OK(decrypt_mode)
- ? ENCTYPE_NAME(decrypt_mode)
- : "(unknown)",
- decrypt_mode);
- encrypt_send_request_end();
- }
-}
-
-void
-encrypt_session_key(Session_Key *key, int server)
-{
- Encryptions *ep = encryptions;
-
- havesessionkey = 1;
-
- while (ep->type) {
- if (ep->session)
- (*ep->session)(key, server);
- ++ep;
- }
-}
-
-/*
- * Called when ENCRYPT END is received.
- */
-void
-encrypt_end(void)
-{
- decrypt_input = 0;
- if (encrypt_debug_mode)
- printf(">>>%s: Input is back to clear text\r\n", Name);
- if (encrypt_verbose)
- printf("[ Input is now clear text ]\r\n");
-}
-
-/*
- * Called when ENCRYPT REQUEST-END is received.
- */
-void
-encrypt_request_end(void)
-{
- encrypt_send_end();
-}
-
-/*
- * Called when ENCRYPT REQUEST-START is received. If we receive
- * this before a type is picked, then that indicates that the
- * other side wants us to start encrypting data as soon as we
- * can.
- */
-void
-encrypt_request_start(unsigned char *data, int cnt)
-{
- if (encrypt_mode == 0) {
- if (Server)
- autoencrypt = 1;
- return;
- }
- encrypt_start_output(encrypt_mode);
-}
-
-static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT };
-
-static void
-encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len)
-{
- Encryptions *ep;
- int dir = kp->dir;
- int ret = 0;
-
- if (!(ep = (*kp->getcrypt)(*kp->modep))) {
- if (len == 0)
- return;
- kp->keylen = 0;
- } else if (len == 0) {
- /*
- * Empty option, indicates a failure.
- */
- if (kp->keylen == 0)
- return;
- kp->keylen = 0;
- if (ep->keyid)
- (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
-
- } else if ((len != kp->keylen) || (memcmp(keyid,kp->keyid,len) != 0)) {
- /*
- * Length or contents are different
- */
- kp->keylen = len;
- memcpy(kp->keyid,keyid, len);
- if (ep->keyid)
- (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
- } else {
- if (ep->keyid)
- ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen);
- if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt)
- encrypt_start_output(*kp->modep);
- return;
- }
-
- encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0);
-}
-
-void encrypt_enc_keyid(unsigned char *keyid, int len)
-{
- encrypt_keyid(&ki[1], keyid, len);
-}
-
-void encrypt_dec_keyid(unsigned char *keyid, int len)
-{
- encrypt_keyid(&ki[0], keyid, len);
-}
-
-
-void encrypt_send_keyid(int dir, unsigned char *keyid, int keylen, int saveit)
-{
- unsigned char *strp;
-
- str_keyid[3] = (dir == DIR_ENCRYPT)
- ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID;
- if (saveit) {
- struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1];
- memcpy(kp->keyid,keyid, keylen);
- kp->keylen = keylen;
- }
-
- for (strp = &str_keyid[4]; keylen > 0; --keylen) {
- if ((*strp++ = *keyid++) == IAC)
- *strp++ = IAC;
- }
- *strp++ = IAC;
- *strp++ = SE;
- telnet_net_write(str_keyid, strp - str_keyid);
- printsub('>', &str_keyid[2], strp - str_keyid - 2);
-}
-
-void
-encrypt_auto(int on)
-{
- if (on < 0)
- autoencrypt ^= 1;
- else
- autoencrypt = on ? 1 : 0;
-}
-
-void
-decrypt_auto(int on)
-{
- if (on < 0)
- autodecrypt ^= 1;
- else
- autodecrypt = on ? 1 : 0;
-}
-
-void
-encrypt_start_output(int type)
-{
- Encryptions *ep;
- unsigned char *p;
- int i;
-
- if (!(ep = findencryption(type))) {
- if (encrypt_debug_mode) {
- printf(">>>%s: Can't encrypt with type %s (%d)\r\n",
- Name,
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type);
- }
- return;
- }
- if (ep->start) {
- i = (*ep->start)(DIR_ENCRYPT, Server);
- if (encrypt_debug_mode) {
- printf(">>>%s: Encrypt start: %s (%d) %s\r\n",
- Name,
- (i < 0) ? "failed" :
- "initial negotiation in progress",
- i, ENCTYPE_NAME(type));
- }
- if (i)
- return;
- }
- p = str_start + 3;
- *p++ = ENCRYPT_START;
- for (i = 0; i < ki[0].keylen; ++i) {
- if ((*p++ = ki[0].keyid[i]) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- telnet_net_write(str_start, p - str_start);
- net_encrypt();
- printsub('>', &str_start[2], p - &str_start[2]);
- /*
- * If we are already encrypting in some mode, then
- * encrypt the ring (which includes our request) in
- * the old mode, mark it all as "clear text" and then
- * switch to the new mode.
- */
- encrypt_output = ep->output;
- encrypt_mode = type;
- if (encrypt_debug_mode)
- printf(">>>%s: Started to encrypt output with type %s\r\n",
- Name, ENCTYPE_NAME(type));
- if (encrypt_verbose)
- printf("[ Output is now encrypted with type %s ]\r\n",
- ENCTYPE_NAME(type));
-}
-
-void
-encrypt_send_end(void)
-{
- if (!encrypt_output)
- return;
-
- str_end[3] = ENCRYPT_END;
- telnet_net_write(str_end, sizeof(str_end));
- net_encrypt();
- printsub('>', &str_end[2], sizeof(str_end) - 2);
- /*
- * Encrypt the output buffer now because it will not be done by
- * netflush...
- */
- encrypt_output = 0;
- if (encrypt_debug_mode)
- printf(">>>%s: Output is back to clear text\r\n", Name);
- if (encrypt_verbose)
- printf("[ Output is now clear text ]\r\n");
-}
-
-void
-encrypt_send_request_start(void)
-{
- unsigned char *p;
- int i;
-
- p = &str_start[3];
- *p++ = ENCRYPT_REQSTART;
- for (i = 0; i < ki[1].keylen; ++i) {
- if ((*p++ = ki[1].keyid[i]) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- telnet_net_write(str_start, p - str_start);
- printsub('>', &str_start[2], p - &str_start[2]);
- if (encrypt_debug_mode)
- printf(">>>%s: Request input to be encrypted\r\n", Name);
-}
-
-void
-encrypt_send_request_end(void)
-{
- str_end[3] = ENCRYPT_REQEND;
- telnet_net_write(str_end, sizeof(str_end));
- printsub('>', &str_end[2], sizeof(str_end) - 2);
-
- if (encrypt_debug_mode)
- printf(">>>%s: Request input to be clear text\r\n", Name);
-}
-
-
-void encrypt_wait(void)
-{
- if (encrypt_debug_mode)
- printf(">>>%s: in encrypt_wait\r\n", Name);
- if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt))
- return;
- while (autoencrypt && !encrypt_output)
- if (telnet_spin())
- return;
-}
-
-int
-encrypt_delay(void)
-{
- if(!havesessionkey ||
- (I_SUPPORT_ENCRYPT & remote_supports_decrypt) == 0 ||
- (I_SUPPORT_DECRYPT & remote_supports_encrypt) == 0)
- return 0;
- if(!(encrypt_output && decrypt_input))
- return 1;
- return 0;
-}
-
-int encrypt_is_encrypting()
-{
- if (encrypt_output && decrypt_input)
- return 1;
- return 0;
-}
-
-void
-encrypt_debug(int mode)
-{
- encrypt_debug_mode = mode;
-}
-
-void encrypt_gen_printsub(unsigned char *data, int cnt,
- unsigned char *buf, int buflen)
-{
- char tbuf[16], *cp;
-
- cnt -= 2;
- data += 2;
- buf[buflen-1] = '\0';
- buf[buflen-2] = '*';
- buflen -= 2;;
- for (; cnt > 0; cnt--, data++) {
- snprintf(tbuf, sizeof(tbuf), " %d", *data);
- for (cp = tbuf; *cp && buflen > 0; --buflen)
- *buf++ = *cp++;
- if (buflen <= 0)
- return;
- }
- *buf = '\0';
-}
-
-void
-encrypt_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
-{
- Encryptions *ep;
- int type = data[1];
-
- for (ep = encryptions; ep->type && ep->type != type; ep++)
- ;
-
- if (ep->printsub)
- (*ep->printsub)(data, cnt, buf, buflen);
- else
- encrypt_gen_printsub(data, cnt, buf, buflen);
-}
-#endif
diff --git a/libexec/telnetd/encrypt.h b/libexec/telnetd/encrypt.h
deleted file mode 100644
index eeeff06e07b..00000000000
--- a/libexec/telnetd/encrypt.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*-
- * 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.
- *
- * from: @(#)encrypt.h 8.1 (Berkeley) 6/4/93
- * $OpenBSD: encrypt.h,v 1.2 2003/06/02 19:38:25 millert Exp $
- * $NetBSD: encrypt.h,v 1.4 1996/02/24 01:15:20 jtk Exp $
- */
-
-/*
- * This source code is no longer held under any constraint of USA
- * `cryptographic laws' since it was exported legally. The cryptographic
- * functions were removed from the code and a "Bones" distribution was
- * made. A Commodity Jurisdiction Request #012-94 was filed with the
- * USA State Department, who handed it to the Commerce department. The
- * code was determined to fall under General License GTDA under ECCN 5D96G,
- * and hence exportable. The cryptographic interfaces were re-added by Eric
- * Young, and then KTH proceeded to maintain the code in the free world.
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America is assumed
- * to require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-/* $KTH: encrypt.h,v 1.4 1997/01/24 23:10:56 assar Exp $ */
-
-#ifndef __ENCRYPT__
-#define __ENCRYPT__
-
-#define DIR_DECRYPT 1
-#define DIR_ENCRYPT 2
-
-#define VALIDKEY(key) ( key[0] | key[1] | key[2] | key[3] | \
- key[4] | key[5] | key[6] | key[7])
-
-#define SAMEKEY(k1, k2) (!memcmp(k1, k2, sizeof(des_cblock)))
-
-typedef struct {
- short type;
- int length;
- unsigned char *data;
-} Session_Key;
-
-typedef struct {
- char *name;
- int type;
- void (*output) (unsigned char *, int);
- int (*input) (int);
- void (*init) (int);
- int (*start) (int, int);
- int (*is) (unsigned char *, int);
- int (*reply) (unsigned char *, int);
- void (*session) (Session_Key *, int);
- int (*keyid) (int, unsigned char *, int *);
- void (*printsub) (unsigned char *, int, unsigned char *, int);
-} Encryptions;
-
-#define SK_DES 1 /* Matched Kerberos v5 KEYTYPE_DES */
-
-#include "enc-proto.h"
-
-extern int encrypt_debug_mode;
-extern int (*decrypt_input) (int);
-extern void (*encrypt_output) (unsigned char *, int);
-#endif
diff --git a/libexec/telnetd/ext.h b/libexec/telnetd/ext.h
deleted file mode 100644
index a2ffa2b2d37..00000000000
--- a/libexec/telnetd/ext.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * 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.
- *
- * @(#)ext.h 8.2 (Berkeley) 12/15/93
- */
-
-/* $KTH: ext.h,v 1.22 2001/04/24 23:12:11 assar Exp $ */
-
-#ifndef __EXT_H__
-#define __EXT_H__
-
-#include <arpa/telnet.h>
-
-/*
- * Telnet server variable declarations
- */
-extern char options[256];
-extern char do_dont_resp[256];
-extern char will_wont_resp[256];
-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 */
-extern int require_otp;
-#ifdef AUTHENTICATION
-extern int auth_level;
-#endif
-extern char *new_login;
-
-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 ourpty, net;
-extern char *line;
-extern int SYNCHing; /* we are in TELNET SYNCH mode */
-
-int telnet_net_write (unsigned char *str, int len);
-void net_encrypt (void);
-int telnet_spin (void);
-char *telnet_getenv (const char *val);
-char *telnet_gets (char *prompt, char *result, int length, int echo);
-void get_slc_defaults (void);
-void telrcv (void);
-void send_do (int option, int init);
-void willoption (int option);
-void send_dont (int option, int init);
-void wontoption (int option);
-void send_will (int option, int init);
-void dooption (int option);
-void send_wont (int option, int init);
-void dontoption (int option);
-void suboption (void);
-void doclientstat (void);
-void send_status (void);
-void init_termbuf (void);
-void set_termbuf (void);
-int spcset (int func, cc_t *valp, cc_t **valpp);
-void set_utid (void);
-int getpty (int *ptynum);
-int tty_isecho (void);
-int tty_flowmode (void);
-int tty_restartany (void);
-void tty_setecho (int on);
-int tty_israw (void);
-void tty_binaryin (int on);
-void tty_binaryout (int on);
-int tty_isbinaryin (void);
-int tty_isbinaryout (void);
-int tty_issofttab (void);
-void tty_setsofttab (int on);
-int tty_islitecho (void);
-void tty_setlitecho (int on);
-int tty_iscrnl (void);
-void tty_tspeed (int val);
-void tty_rspeed (int val);
-void getptyslave (void);
-int cleanopen (char *line);
-void startslave (const char *host, const char *, int autologin, char *autoname);
-void init_env (void);
-void start_login (const char *host, int autologin, char *name);
-void cleanup (int sig);
-int main (int argc, char **argv);
-int getterminaltype (char *name, size_t);
-void _gettermname (void);
-int terminaltypeok (char *s);
-void my_telnet (int f, int p, const char*, const char *, int, char*);
-void interrupt (void);
-void sendbrk (void);
-void sendsusp (void);
-void recv_ayt (void);
-void doeof (void);
-void flowstat (void);
-void clientstat (int code, int parm1, int parm2);
-int ttloop (void);
-int stilloob (int s);
-void ptyflush (void);
-char *nextitem (char *current);
-void netclear (void);
-void netflush (void);
-void writenet (unsigned char *ptr, int len);
-void fatal (int f, char *msg);
-void fatalperror (int f, const char *msg);
-void fatalperror_errno (int f, const char *msg, int error);
-void edithost (char *pat, char *host);
-void putstr (char *s);
-void putchr (int cc);
-void putf (char *cp, char *where);
-void printoption (char *fmt, int option);
-void printsub (int direction, unsigned char *pointer, int length);
-void printdata (char *tag, char *ptr, int cnt);
-int login_tty(int t);
-
-#ifdef ENCRYPTION
-extern void (*encrypt_output) (unsigned char *, int);
-extern int (*decrypt_input) (int);
-extern char *nclearto;
-#endif
-
-
-/*
- * The following are some clocks used to decide how to interpret
- * the relationship between various variables.
- */
-
-struct clocks_t{
- 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 */
-};
-extern struct clocks_t clocks;
-
-extern int log_unauth;
-extern int no_warn;
-
-#ifdef STREAMSPTY
-extern int really_stream;
-#endif
-
-#ifndef USE_IM
-# ifdef CRAY
-# define USE_IM "Cray UNICOS (%h) (%t)"
-# endif
-# ifdef _AIX
-# define USE_IM "%s %v.%r (%h) (%t)"
-# endif
-# ifndef USE_IM
-# define USE_IM "%s %r (%h) (%t)"
-# endif
-#endif
-
-#define DEFAULT_IM "\r\n\r\n" USE_IM "\r\n\r\n\r\n"
-
-#endif /* __EXT_H__ */
diff --git a/libexec/telnetd/genget.c b/libexec/telnetd/genget.c
deleted file mode 100644
index 49503c238ea..00000000000
--- a/libexec/telnetd/genget.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* $OpenBSD: genget.c,v 1.2 2003/06/02 19:38:25 millert 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.
- */
-
-#ifndef lint
-/* from: static char sccsid[] = "@(#)genget.c 8.2 (Berkeley) 5/30/95"; */
-/* from: static char *rcsid = "$NetBSD: genget.c,v 1.5 1996/02/24 01:15:21 jtk Exp $"; */
-static char *rcsid = "$OpenBSD: genget.c,v 1.2 2003/06/02 19:38:25 millert Exp $";
-#endif /* not lint */
-
-/* $KTH: genget.c,v 1.6 1997/05/04 09:01:34 assar Exp $ */
-
-#include <ctype.h>
-#include "misc-proto.h"
-
-#define LOWER(x) (isupper((int)x) ? tolower((int)x) : (x))
-/*
- * The prefix function returns 0 if *s1 is not a prefix
- * of *s2. If *s1 exactly matches *s2, the negative of
- * the length is returned. If *s1 is a prefix of *s2,
- * the length of *s1 is returned.
- */
-int
-isprefix(char *s1, char *s2)
-{
- char *os1;
- char c1, c2;
-
- if (*s1 == '\0')
- return(-1);
- os1 = s1;
- c1 = *s1;
- c2 = *s2;
- while (LOWER(c1) == LOWER(c2)) {
- if (c1 == '\0')
- break;
- c1 = *++s1;
- c2 = *++s2;
- }
- return(*s1 ? 0 : (*s2 ? (s1 - os1) : (os1 - s1)));
-}
-
-static char *ambiguous; /* special return value for command routines */
-
-char **
-genget(char *name, char **table, int stlen)
- /* name to match */
- /* name entry in table */
-
-{
- char **c, **found;
- int n;
-
- if (name == 0)
- return 0;
-
- found = 0;
- for (c = table; *c != 0; c = (char **)((char *)c + stlen)) {
- if ((n = isprefix(name, *c)) == 0)
- continue;
- if (n < 0) /* exact match */
- return(c);
- if (found)
- return(&ambiguous);
- found = c;
- }
- return(found);
-}
-
-/*
- * Function call version of Ambiguous()
- */
-int
-Ambiguous(void *s)
-{
- return((char **)s == &ambiguous);
-}
diff --git a/libexec/telnetd/global.c b/libexec/telnetd/global.c
deleted file mode 100644
index c7d008af540..00000000000
--- a/libexec/telnetd/global.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.
- */
-
-/* a *lot* of ugly global definitions that really should be removed...
- */
-
-#include "telnetd.h"
-
-/* RCSID("$KTH: global.c,v 1.12 1997/05/11 06:29:59 assar Exp $"); */
-
-/*
- * Telnet server variable declarations
- */
-char options[256];
-char do_dont_resp[256];
-char will_wont_resp[256];
-int linemode; /* linemode on/off */
-int flowmode; /* current flow control state */
-int restartany; /* restart output on any character state */
-#ifdef DIAGNOSTICS
-int diagnostic; /* telnet diagnostic capabilities */
-#endif /* DIAGNOSTICS */
-
-slcfun slctab[NSLC + 1]; /* slc mapping table */
-
-char terminaltype[41];
-
-/*
- * I/O data buffers, pointers, and counters.
- */
-char ptyobuf[BUFSIZ+NETSLOP], *pfrontp, *pbackp;
-
-char netibuf[BUFSIZ], *netip;
-
-char netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp;
-char *neturg; /* one past last bye of urgent data */
-
-int pcc, ncc;
-
-int ourpty, net;
-int SYNCHing; /* we are in TELNET SYNCH mode */
-
-/*
- * The following are some clocks used to decide how to interpret
- * the relationship between various variables.
- */
-
-struct clocks_t clocks;
-
-
-/* whether to log unauthenticated login attempts */
-int log_unauth;
-
-/* do not print warning if connection is not encrypted */
-int no_warn;
-
-/*
- * This function appends data to nfrontp and advances nfrontp.
- */
-
-int
-output_data (const char *format, ...)
-{
- va_list args;
- size_t remaining;
- int n;
-
- va_start(args, format);
- remaining = BUFSIZ - (nfrontp - netobuf);
- if (remaining == 0) {
- va_end(args);
- return remaining;
- }
- if ((n = vsnprintf(nfrontp, remaining, format, args)) >= remaining || n < 0)
- n = strlen(nfrontp);
- nfrontp += n;
- va_end(args);
- return n;
-}
diff --git a/libexec/telnetd/kerberos.c b/libexec/telnetd/kerberos.c
deleted file mode 100644
index dde320a055f..00000000000
--- a/libexec/telnetd/kerberos.c
+++ /dev/null
@@ -1,751 +0,0 @@
-/* $OpenBSD: kerberos.c,v 1.2 2003/06/02 19:38:25 millert 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.
- */
-
- /*
- * This source code is no longer held under any constraint of USA
- * `cryptographic laws' since it was exported legally. The cryptographic
- * functions were removed from the code and a "Bones" distribution was
- * made. A Commodity Jurisdiction Request #012-94 was filed with the
- * USA State Department, who handed it to the Commerce department. The
- * code was determined to fall under General License GTDA under ECCN 5D96G,
- * and hence exportable. The cryptographic interfaces were re-added by Eric
- * Young, and then KTH proceeded to maintain the code in the free world.
- *
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America is assumed
- * to require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-/* $KTH: kerberos.c,v 1.50 2000/11/23 02:28:06 joda Exp $" */
-
-#ifdef KRB4
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <resolv.h>
-#include <arpa/telnet.h>
-#include <des.h>
-#include <kerberosIV/krb.h>
-#include <pwd.h>
-#include <syslog.h>
-#include <err.h>
-#include "encrypt.h"
-#include "auth.h"
-#include "misc.h"
-
-int kerberos4_cksum (unsigned char *, int);
-extern int auth_debug_mode;
-
-static unsigned char str_data[2048] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
- AUTHTYPE_KERBEROS_V4, };
-
-#define KRB_AUTH 0 /* Authentication data follows */
-#define KRB_REJECT 1 /* Rejected (reason might follow) */
-#define KRB_ACCEPT 2 /* Accepted */
-#define KRB_CHALLENGE 3 /* Challenge for mutual auth. */
-#define KRB_RESPONSE 4 /* Response for mutual auth. */
-
-#define KRB_FORWARD 5 /* */
-#define KRB_FORWARD_ACCEPT 6 /* */
-#define KRB_FORWARD_REJECT 7 /* */
-
-#define KRB_SERVICE_NAME "rcmd"
-
-static KTEXT_ST auth;
-static char name[ANAME_SZ];
-static AUTH_DAT adat;
-static des_cblock session_key;
-static des_cblock cred_session;
-static des_key_schedule sched;
-static des_cblock challenge;
-static int auth_done; /* XXX */
-
-static int pack_cred(CREDENTIALS *cred, unsigned char *buf);
-static int unpack_cred(unsigned char *buf, int len, CREDENTIALS *cred);
-
-int
-check_krb4_tickets() {
- int ret;
- int retval = 0;
- char *file;
- krb_principal princ;
-
- file = getenv("KRBTKFILE");
- if(file == NULL)
- file = TKT_FILE;
-
- ret = krb_get_tf_realm(file, princ.realm);
- switch(ret) {
- case NO_TKT_FIL:
- retval = 0;
- goto done;
- case 0:
- retval = 1;
- goto done;
- default:
- errx(1, "krb_get_tf_realm: %d", ret);
- }
-
- done:
- return retval;
-}
-
-static int
-Data(Authenticator *ap, int type, const void *d, int c)
-{
- unsigned char *p = str_data + 4;
- const unsigned char *cd = (const unsigned char *)d;
-
- if (c == -1)
- c = strlen((const char *)cd);
-
- if (auth_debug_mode) {
- printf("%s:%d: [%d] (%d)",
- str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
- str_data[3],
- type, c);
- printd(d, c);
- printf("\r\n");
- }
- *p++ = ap->type;
- *p++ = ap->way;
- *p++ = type;
- while (c-- > 0) {
- if ((*p++ = *cd++) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- if (str_data[3] == TELQUAL_IS)
- printsub('>', &str_data[2], p - (&str_data[2]));
- return(telnet_net_write(str_data, p - str_data));
-}
-
-int
-kerberos4_init(Authenticator *ap, int server)
-{
- FILE *fp;
-
- if (server) {
- str_data[3] = TELQUAL_REPLY;
- if ((fp = fopen(KEYFILE, "r")) == NULL)
- return(0);
- fclose(fp);
- } else {
- str_data[3] = TELQUAL_IS;
- }
- return(1);
-}
-
-char dst_realm_buf[REALM_SZ], *dest_realm = NULL;
-int dst_realm_sz = REALM_SZ;
-
-static int
-kerberos4_send(char *name, Authenticator *ap)
-{
- KTEXT_ST auth;
- char instance[INST_SZ];
- char *realm;
- CREDENTIALS cred;
- int r;
-
- if(check_krb4_tickets() != 1)
- return 0;
-
- if (!UserNameRequested) {
- if (auth_debug_mode) {
- printf("Kerberos V4: no user name supplied\r\n");
- }
- return(0);
- }
-
- memset(instance, 0, sizeof(instance));
-
- strlcpy (instance,
- krb_get_phost(RemoteHostName),
- INST_SZ);
-
- realm = dest_realm ? dest_realm : krb_realmofhost(RemoteHostName);
-
- if (!realm) {
- printf("Kerberos V4: no realm for %s\r\n", RemoteHostName);
- return(0);
- }
- printf("[ Trying %s (%s.%s@%s) ... ]\r\n", name,
- KRB_SERVICE_NAME, instance, realm);
- r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0L);
- if (r) {
- printf("mk_req failed: %s\r\n", krb_get_err_text(r));
- return(0);
- }
- r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred);
- if (r) {
- printf("get_cred failed: %s\r\n", krb_get_err_text(r));
- return(0);
- }
- if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
- if (auth_debug_mode)
- printf("Not enough room for user name\r\n");
- return(0);
- }
- if (auth_debug_mode)
- printf("Sent %d bytes of authentication data\r\n", auth.length);
- if (!Data(ap, KRB_AUTH, (void *)auth.dat, auth.length)) {
- if (auth_debug_mode)
- printf("Not enough room for authentication data\r\n");
- return(0);
- }
-#ifdef ENCRYPTION
- /* create challenge */
- if ((ap->way & AUTH_HOW_MASK)==AUTH_HOW_MUTUAL) {
- int i;
-
- des_key_sched(&cred.session, sched);
- memcpy (&cred_session, &cred.session, sizeof(cred_session));
- des_init_random_number_generator(&cred.session);
- des_new_random_key(&session_key);
- des_ecb_encrypt(&session_key, &session_key, sched, 0);
- des_ecb_encrypt(&session_key, &challenge, sched, 0);
-
- /*
- old code
- Some CERT Advisory thinks this is a bad thing...
-
- des_init_random_number_generator(&cred.session);
- des_new_random_key(&challenge);
- des_ecb_encrypt(&challenge, &session_key, sched, 1);
- */
-
- /*
- * Increment the challenge by 1, and encrypt it for
- * later comparison.
- */
- for (i = 7; i >= 0; --i)
- if(++challenge[i] != 0) /* No carry! */
- break;
- des_ecb_encrypt(&challenge, &challenge, sched, 1);
- }
-
-#endif
-
- if (auth_debug_mode) {
- printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length));
- printd(auth.dat, auth.length);
- printf("\r\n");
- printf("Sent Kerberos V4 credentials to server\r\n");
- }
- return(1);
-}
-int
-kerberos4_send_mutual(Authenticator *ap)
-{
- return kerberos4_send("mutual KERBEROS4", ap);
-}
-
-int
-kerberos4_send_oneway(Authenticator *ap)
-{
- return kerberos4_send("KERBEROS4", ap);
-}
-
-void
-kerberos4_is(Authenticator *ap, unsigned char *data, int cnt)
-{
- struct sockaddr_in addr;
- char realm[REALM_SZ];
- char instance[INST_SZ];
- int r;
- socklen_t addr_len;
-
- if (cnt-- < 1)
- return;
- switch (*data++) {
- case KRB_AUTH:
- if (krb_get_lrealm(realm, 1) != KSUCCESS) {
- Data(ap, KRB_REJECT, (void *)"No local V4 Realm.", -1);
- auth_finished(ap, AUTH_REJECT);
- if (auth_debug_mode)
- printf("No local realm\r\n");
- return;
- }
- memmove(auth.dat, data, auth.length = cnt);
- if (auth_debug_mode) {
- printf("Got %d bytes of authentication data\r\n", cnt);
- printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length));
- printd(auth.dat, auth.length);
- printf("\r\n");
- }
- k_getsockinst(0, instance, sizeof(instance));
- addr_len = sizeof(addr);
- if(getpeername(0, (struct sockaddr *)&addr, &addr_len) < 0) {
- if(auth_debug_mode)
- printf("getpeername failed\r\n");
- Data(ap, KRB_REJECT, "getpeername failed", -1);
- auth_finished(ap, AUTH_REJECT);
- return;
- }
- if (addr.sin_family != AF_INET) {
- if (auth_debug_mode)
- printf("unknown address family: %d\r\n", addr.sin_family);
- Data(ap, KRB_REJECT, "bad address family", -1);
- auth_finished(ap, AUTH_REJECT);
- return;
- }
-
- r = krb_rd_req(&auth, KRB_SERVICE_NAME,
- instance, addr.sin_addr.s_addr, &adat, "");
- if (r) {
- if (auth_debug_mode)
- printf("Kerberos failed him as %s\r\n", name);
- Data(ap, KRB_REJECT, (void *)krb_get_err_text(r), -1);
- auth_finished(ap, AUTH_REJECT);
- return;
- }
- /* save the session key */
- memmove(session_key, adat.session, sizeof(adat.session));
- krb_kntoln(&adat, name);
-
- if (UserNameRequested && !kuserok(&adat, UserNameRequested)){
- char ts[MAXPATHLEN];
- struct passwd *pw = getpwnam(UserNameRequested);
-
- if(pw){
- snprintf(ts, sizeof(ts),
- "%s%u",
- TKT_ROOT,
- (unsigned)pw->pw_uid);
- esetenv("KRBTKFILE", ts, 1);
-
- if (pw->pw_uid == 0)
- syslog(LOG_INFO|LOG_AUTH,
- "ROOT Kerberos login from %s on %s",
- krb_unparse_name_long(adat.pname,
- adat.pinst,
- adat.prealm),
- RemoteHostName);
- }
- Data(ap, KRB_ACCEPT, NULL, 0);
- } else {
- char *msg;
-
- asprintf (&msg, "user `%s' is not authorized to "
- "login as `%s'",
- krb_unparse_name_long(adat.pname,
- adat.pinst,
- adat.prealm),
- UserNameRequested ? UserNameRequested : "<nobody>");
- if (msg == NULL)
- Data(ap, KRB_REJECT, NULL, 0);
- else {
- Data(ap, KRB_REJECT, (void *)msg, -1);
- free(msg);
- }
- auth_finished(ap, AUTH_REJECT);
- break;
- }
- auth_finished(ap, AUTH_USER);
- break;
-
- case KRB_CHALLENGE:
-#ifndef ENCRYPTION
- Data(ap, KRB_RESPONSE, NULL, 0);
-#else
- if(!VALIDKEY(session_key)){
- Data(ap, KRB_RESPONSE, NULL, 0);
- break;
- }
- des_key_sched(&session_key, sched);
- {
- des_cblock d_block;
- int i;
- Session_Key skey;
-
- memmove(d_block, data, sizeof(d_block));
-
- /* make a session key for encryption */
- des_ecb_encrypt(&d_block, &session_key, sched, 1);
- skey.type=SK_DES;
- skey.length=8;
- skey.data=session_key;
- encrypt_session_key(&skey, 1);
-
- /* decrypt challenge, add one and encrypt it */
- des_ecb_encrypt(&d_block, &challenge, sched, 0);
- for (i = 7; i >= 0; i--)
- if(++challenge[i] != 0)
- break;
- des_ecb_encrypt(&challenge, &challenge, sched, 1);
- Data(ap, KRB_RESPONSE, (void *)challenge, sizeof(challenge));
- }
-#endif
- break;
-
- case KRB_FORWARD:
- {
- des_key_schedule ks;
- unsigned char netcred[sizeof(CREDENTIALS)];
- CREDENTIALS cred;
- int ret;
- if(cnt > sizeof(cred))
- abort();
-
- memcpy (session_key, adat.session, sizeof(session_key));
- des_set_key(&session_key, ks);
- des_pcbc_encrypt((void*)data, (void*)netcred, cnt,
- ks, &session_key, DES_DECRYPT);
- unpack_cred(netcred, cnt, &cred);
- {
- if(strcmp(cred.service, KRB_TICKET_GRANTING_TICKET) ||
- strncmp(cred.instance, cred.realm, sizeof(cred.instance)) ||
- cred.lifetime < 0 || cred.lifetime > 255 ||
- cred.kvno < 0 || cred.kvno > 255 ||
- cred.issue_date < 0 ||
- cred.issue_date > time(0) + CLOCK_SKEW ||
- strncmp(cred.pname, adat.pname, sizeof(cred.pname)) ||
- strncmp(cred.pinst, adat.pinst, sizeof(cred.pinst))){
- Data(ap, KRB_FORWARD_REJECT, "Bad credentials", -1);
- }else{
- if((ret = tf_setup(&cred,
- cred.pname,
- cred.pinst)) == KSUCCESS){
- struct passwd *pw = getpwnam(UserNameRequested);
-
- if (pw)
- chown(tkt_string(), pw->pw_uid, pw->pw_gid);
- Data(ap, KRB_FORWARD_ACCEPT, 0, 0);
- } else{
- Data(ap, KRB_FORWARD_REJECT,
- krb_get_err_text(ret), -1);
- }
- }
- }
- memset(data, 0, cnt);
- memset(ks, 0, sizeof(ks));
- memset(&cred, 0, sizeof(cred));
- }
-
- break;
-
- default:
- if (auth_debug_mode)
- printf("Unknown Kerberos option %d\r\n", data[-1]);
- Data(ap, KRB_REJECT, 0, 0);
- break;
- }
-}
-
-void
-kerberos4_reply(Authenticator *ap, unsigned char *data, int cnt)
-{
- Session_Key skey;
-
- if (cnt-- < 1)
- return;
- switch (*data++) {
- case KRB_REJECT:
- if(auth_done){ /* XXX Ick! */
- printf("[ Kerberos V4 received unknown opcode ]\r\n");
- }else{
- printf("[ Kerberos V4 refuses authentication ");
- if (cnt > 0)
- printf("because %.*s ", cnt, data);
- printf("]\r\n");
- auth_send_retry();
- }
- return;
- case KRB_ACCEPT:
- printf("[ Kerberos V4 accepts you ]\r\n");
- auth_done = 1;
- if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- /*
- * Send over the encrypted challenge.
- */
- Data(ap, KRB_CHALLENGE, session_key,
- sizeof(session_key));
- des_ecb_encrypt(&session_key, &session_key, sched, 1);
- skey.type = SK_DES;
- skey.length = 8;
- skey.data = session_key;
- encrypt_session_key(&skey, 0);
-#if 0
- kerberos4_forward(ap, &cred_session);
-#endif
- return;
- }
- auth_finished(ap, AUTH_USER);
- return;
- case KRB_RESPONSE:
- /* make sure the response is correct */
- if ((cnt != sizeof(des_cblock)) ||
- (memcmp(data, challenge, sizeof(challenge)))){
- printf("[ Kerberos V4 challenge failed!!! ]\r\n");
- auth_send_retry();
- return;
- }
- printf("[ Kerberos V4 challenge successful ]\r\n");
- auth_finished(ap, AUTH_USER);
- break;
- case KRB_FORWARD_ACCEPT:
- printf("[ Kerberos V4 accepted forwarded credentials ]\r\n");
- break;
- case KRB_FORWARD_REJECT:
- printf("[ Kerberos V4 rejected forwarded credentials: `%.*s']\r\n",
- cnt, data);
- break;
- default:
- if (auth_debug_mode)
- printf("Unknown Kerberos option %d\r\n", data[-1]);
- return;
- }
-}
-
-int
-kerberos4_status(Authenticator *ap, char *name, size_t name_sz, int level)
-{
- if (level < AUTH_USER)
- return(level);
-
- if (UserNameRequested && !kuserok(&adat, UserNameRequested)) {
- strlcpy(name, UserNameRequested, name_sz);
- return(AUTH_VALID);
- } else
- return(AUTH_USER);
-}
-
-#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
-#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
-
-void
-kerberos4_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
-{
- int i;
-
- buf[buflen-1] = '\0'; /* make sure its NULL terminated */
- buflen -= 1;
-
- switch(data[3]) {
- case KRB_REJECT: /* Rejected (reason might follow) */
- strlcpy((char *)buf, " REJECT ", buflen);
- goto common;
-
- case KRB_ACCEPT: /* Accepted (name might follow) */
- strlcpy((char *)buf, " ACCEPT ", buflen);
- common:
- BUMP(buf, buflen);
- if (cnt <= 4)
- break;
- ADDC(buf, buflen, '"');
- for (i = 4; i < cnt; i++)
- ADDC(buf, buflen, data[i]);
- ADDC(buf, buflen, '"');
- ADDC(buf, buflen, '\0');
- break;
-
- case KRB_AUTH: /* Authentication data follows */
- strlcpy((char *)buf, " AUTH", buflen);
- goto common2;
-
- case KRB_CHALLENGE:
- strlcpy((char *)buf, " CHALLENGE", buflen);
- goto common2;
-
- case KRB_RESPONSE:
- strlcpy((char *)buf, " RESPONSE", buflen);
- goto common2;
-
- default:
- snprintf(buf, buflen, " %d (unknown)", data[3]);
- common2:
- BUMP(buf, buflen);
- for (i = 4; i < cnt; i++) {
- snprintf(buf, buflen, " %d", data[i]);
- BUMP(buf, buflen);
- }
- break;
- }
-}
-
-int
-kerberos4_cksum(unsigned char *d, int n)
-{
- int ck = 0;
-
- /*
- * A comment is probably needed here for those not
- * well versed in the "C" language. Yes, this is
- * supposed to be a "switch" with the body of the
- * "switch" being a "while" statement. The whole
- * purpose of the switch is to allow us to jump into
- * the middle of the while() loop, and then not have
- * to do any more switch()s.
- *
- * Some compilers will spit out a warning message
- * about the loop not being entered at the top.
- */
- switch (n&03)
- while (n > 0) {
- case 0:
- ck ^= (int)*d++ << 24;
- --n;
- case 3:
- ck ^= (int)*d++ << 16;
- --n;
- case 2:
- ck ^= (int)*d++ << 8;
- --n;
- case 1:
- ck ^= (int)*d++;
- --n;
- }
- return(ck);
-}
-
-static int
-pack_cred(CREDENTIALS *cred, unsigned char *buf)
-{
- unsigned char *p = buf;
-
- memcpy (p, cred->service, ANAME_SZ);
- p += ANAME_SZ;
- memcpy (p, cred->instance, INST_SZ);
- p += INST_SZ;
- memcpy (p, cred->realm, REALM_SZ);
- p += REALM_SZ;
- memcpy(p, cred->session, 8);
- p += 8;
- p += krb_put_int(cred->lifetime, p, 4, 4);
- p += krb_put_int(cred->kvno, p, 4, 4);
- p += krb_put_int(cred->ticket_st.length, p, 4, 4);
- memcpy(p, cred->ticket_st.dat, cred->ticket_st.length);
- p += cred->ticket_st.length;
- p += krb_put_int(0, p, 4, 4);
- p += krb_put_int(cred->issue_date, p, 4, 4);
- memcpy (p, cred->pname, ANAME_SZ);
- p += ANAME_SZ;
- memcpy (p, cred->pinst, INST_SZ);
- p += INST_SZ;
- return p - buf;
-}
-
-static int
-unpack_cred(unsigned char *buf, int len, CREDENTIALS *cred)
-{
- unsigned char *p = buf;
- u_int32_t tmp;
-
- strncpy (cred->service, p, ANAME_SZ);
- cred->service[ANAME_SZ - 1] = '\0';
- p += ANAME_SZ;
- strncpy (cred->instance, p, INST_SZ);
- cred->instance[INST_SZ - 1] = '\0';
- p += INST_SZ;
- strncpy (cred->realm, p, REALM_SZ);
- cred->realm[REALM_SZ - 1] = '\0';
- p += REALM_SZ;
-
- memcpy(cred->session, p, 8);
- p += 8;
- p += krb_get_int(p, &tmp, 4, 0);
- cred->lifetime = tmp;
- p += krb_get_int(p, &tmp, 4, 0);
- cred->kvno = tmp;
-
- p += krb_get_int(p, &cred->ticket_st.length, 4, 0);
- memcpy(cred->ticket_st.dat, p, cred->ticket_st.length);
- p += cred->ticket_st.length;
- p += krb_get_int(p, &tmp, 4, 0);
- cred->ticket_st.mbz = 0;
- p += krb_get_int(p, (u_int32_t *)&cred->issue_date, 4, 0);
-
- strncpy (cred->pname, p, ANAME_SZ);
- cred->pname[ANAME_SZ - 1] = '\0';
- p += ANAME_SZ;
- strncpy (cred->pinst, p, INST_SZ);
- cred->pinst[INST_SZ - 1] = '\0';
- p += INST_SZ;
- return 0;
-}
-
-
-int
-kerberos4_forward(Authenticator *ap, void *v)
-{
- des_cblock *key = (des_cblock *)v;
- CREDENTIALS cred;
- char *realm;
- des_key_schedule ks;
- int len;
- unsigned char netcred[sizeof(CREDENTIALS)];
- int ret;
-
- realm = krb_realmofhost(RemoteHostName);
- if(realm == NULL)
- return -1;
- memset(&cred, 0, sizeof(cred));
- ret = krb_get_cred(KRB_TICKET_GRANTING_TICKET,
- realm,
- realm,
- &cred);
- if(ret)
- return ret;
- des_set_key(key, ks);
- len = pack_cred(&cred, netcred);
- des_pcbc_encrypt((void*)netcred, (void*)netcred, len,
- ks, key, DES_ENCRYPT);
- memset(ks, 0, sizeof(ks));
- Data(ap, KRB_FORWARD, netcred, len);
- memset(netcred, 0, sizeof(netcred));
- return 0;
-}
-
-#endif /* KRB4 */
-
diff --git a/libexec/telnetd/kerberos5.c b/libexec/telnetd/kerberos5.c
deleted file mode 100644
index d0ff32dcf78..00000000000
--- a/libexec/telnetd/kerberos5.c
+++ /dev/null
@@ -1,910 +0,0 @@
-/* $OpenBSD: kerberos5.c,v 1.2 2003/06/02 19:38:25 millert 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.
- */
-
-/*
- * This source code is no longer held under any constraint of USA
- * `cryptographic laws' since it was exported legally. The cryptographic
- * functions were removed from the code and a "Bones" distribution was
- * made. A Commodity Jurisdiction Request #012-94 was filed with the
- * USA State Department, who handed it to the Commerce department. The
- * code was determined to fall under General License GTDA under ECCN 5D96G,
- * and hence exportable. The cryptographic interfaces were re-added by Eric
- * Young, and then KTH proceeded to maintain the code in the free world.
- *
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-/* $KTH: kerberos5.c,v 1.47 2001/01/09 18:45:33 assar Exp $ */
-
-#ifdef KRB5
-
-#include <arpa/telnet.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <pwd.h>
-#include <errno.h>
-#define Authenticator k5_Authenticator
-#include <kerberosV/krb5.h>
-#undef Authenticator
-#include <err.h>
-
-#include "encrypt.h"
-#include "auth.h"
-#include "misc.h"
-
-#if defined(DCE)
-int dfsk5ok = 0;
-int dfspag = 0;
-int dfsfwd = 0;
-#endif
-
-int forward_flags = 0; /* Flags get set in telnet/main.c on -f and -F */
-
-int forward(int);
-int forwardable(int);
-
-/* These values need to be the same as those defined in telnet/main.c. */
-/* Either define them in both places, or put in some common header file. */
-#define OPTS_FORWARD_CREDS 0x00000002
-#define OPTS_FORWARDABLE_CREDS 0x00000001
-
-
-void kerberos5_forward (Authenticator *);
-
-static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
- AUTHTYPE_KERBEROS_V5, };
-
-#define KRB_AUTH 0 /* Authentication data follows */
-#define KRB_REJECT 1 /* Rejected (reason might follow) */
-#define KRB_ACCEPT 2 /* Accepted */
-#define KRB_RESPONSE 3 /* Response for mutual auth. */
-
-#define KRB_FORWARD 4 /* Forwarded credentials follow */
-#define KRB_FORWARD_ACCEPT 5 /* Forwarded credentials accepted */
-#define KRB_FORWARD_REJECT 6 /* Forwarded credentials rejected */
-
-static krb5_data auth;
-static krb5_ticket *ticket;
-
-static krb5_context context;
-static krb5_auth_context auth_context;
-
-int
-check_krb5_tickets()
-{
- krb5_error_code ret;
- krb5_context context;
- krb5_ccache ccache;
- krb5_principal principal;
- int retval = 1;
-
- ret = krb5_init_context(&context);
- if(ret)
- errx(1, "krb5_init_context failt: %d", ret);
-
- ret = krb5_cc_default(context, &ccache);
- if(ret)
- errx(1, "krb5_cc_default: %d", ret);
-
- ret = krb5_cc_get_principal (context, ccache, &principal);
- switch(ret) {
- case ENOENT:
- retval = 0;
- goto done;
- case 0:
- retval = 1;
- goto done;
- default:
- errx(1, "krb5_cc_get_principal: %d", ret);
- break;
- }
-
- done:
- krb5_free_context(context);
- return retval;
-}
-
-static int
-Data(Authenticator *ap, int type, void *d, int c)
-{
- unsigned char *p = str_data + 4;
- unsigned char *cd = (unsigned char *)d;
-
- if (c == -1)
- c = strlen(cd);
-
- if (auth_debug_mode) {
- printf("%s:%d: [%d] (%d)",
- str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
- str_data[3],
- type, c);
- printd(d, c);
- printf("\r\n");
- }
- *p++ = ap->type;
- *p++ = ap->way;
- *p++ = type;
- while (c-- > 0) {
- if ((*p++ = *cd++) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- if (str_data[3] == TELQUAL_IS)
- printsub('>', &str_data[2], p - &str_data[2]);
- return(telnet_net_write(str_data, p - str_data));
-}
-
-int
-kerberos5_init(Authenticator *ap, int server)
-{
- krb5_error_code ret;
-
- ret = krb5_init_context(&context);
- if (ret)
- return 0;
- if (server) {
- krb5_keytab kt;
- krb5_kt_cursor cursor;
-
- ret = krb5_kt_default(context, &kt);
- if (ret)
- return 0;
-
- ret = krb5_kt_start_seq_get (context, kt, &cursor);
- if (ret) {
- krb5_kt_close (context, kt);
- return 0;
- }
- krb5_kt_end_seq_get (context, kt, &cursor);
- krb5_kt_close (context, kt);
-
- str_data[3] = TELQUAL_REPLY;
- } else
- str_data[3] = TELQUAL_IS;
- return(1);
-}
-
-extern int net;
-static int
-kerberos5_send(char *name, Authenticator *ap)
-{
- krb5_error_code ret;
- krb5_ccache ccache;
- int ap_opts;
- krb5_data cksum_data;
- char foo[2];
-
- if(check_krb5_tickets() != 1)
- return 0;
-
- if (!UserNameRequested) {
- if (auth_debug_mode) {
- printf("Kerberos V5: no user name supplied\r\n");
- }
- return(0);
- }
-
- ret = krb5_cc_default(context, &ccache);
- if (ret) {
- if (auth_debug_mode) {
- printf("Kerberos V5: could not get default ccache: %s\r\n",
- krb5_get_err_text (context, ret));
- }
- return 0;
- }
-
- if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
- ap_opts = AP_OPTS_MUTUAL_REQUIRED;
- else
- ap_opts = 0;
-
- ap_opts |= AP_OPTS_USE_SUBKEY;
-
- ret = krb5_auth_con_init (context, &auth_context);
- if (ret) {
- if (auth_debug_mode) {
- printf("Kerberos V5: krb5_auth_con_init failed (%s)\r\n",
- krb5_get_err_text(context, ret));
- }
- return(0);
- }
-
- ret = krb5_auth_con_setaddrs_from_fd (context,
- auth_context,
- &net);
- if (ret) {
- if (auth_debug_mode) {
- printf ("Kerberos V5:"
- " krb5_auth_con_setaddrs_from_fd failed (%s)\r\n",
- krb5_get_err_text(context, ret));
- }
- return(0);
- }
-
- krb5_auth_con_setkeytype (context, auth_context, KEYTYPE_DES);
-
- foo[0] = ap->type;
- foo[1] = ap->way;
-
- cksum_data.length = sizeof(foo);
- cksum_data.data = foo;
-
-
- {
- krb5_principal service;
- char sname[128];
-
-
- ret = krb5_sname_to_principal (context,
- RemoteHostName,
- NULL,
- KRB5_NT_SRV_HST,
- &service);
- if(ret) {
- if (auth_debug_mode) {
- printf ("Kerberos V5:"
- " krb5_sname_to_principal(%s) failed (%s)\r\n",
- RemoteHostName, krb5_get_err_text(context, ret));
- }
- return 0;
- }
- ret = krb5_unparse_name_fixed(context, service, sname, sizeof(sname));
- if(ret) {
- if (auth_debug_mode) {
- printf ("Kerberos V5:"
- " krb5_unparse_name_fixed failed (%s)\r\n",
- krb5_get_err_text(context, ret));
- }
- return 0;
- }
- printf("[ Trying %s (%s)... ]\r\n", name, sname);
- ret = krb5_mk_req_exact(context, &auth_context, ap_opts,
- service,
- &cksum_data, ccache, &auth);
- krb5_free_principal (context, service);
-
- }
- if (ret) {
- if (1 || auth_debug_mode) {
- printf("Kerberos V5: mk_req failed (%s)\r\n",
- krb5_get_err_text(context, ret));
- }
- return(0);
- }
-
- if (!auth_sendname((unsigned char *)UserNameRequested,
- strlen(UserNameRequested))) {
- if (auth_debug_mode)
- printf("Not enough room for user name\r\n");
- return(0);
- }
- if (!Data(ap, KRB_AUTH, auth.data, auth.length)) {
- if (auth_debug_mode)
- printf("Not enough room for authentication data\r\n");
- return(0);
- }
- if (auth_debug_mode) {
- printf("Sent Kerberos V5 credentials to server\r\n");
- }
- return(1);
-}
-
-int
-kerberos5_send_mutual(Authenticator *ap)
-{
- return kerberos5_send("mutual KERBEROS5", ap);
-}
-
-int
-kerberos5_send_oneway(Authenticator *ap)
-{
- return kerberos5_send("KERBEROS5", ap);
-}
-
-void
-kerberos5_is(Authenticator *ap, unsigned char *data, int cnt)
-{
- krb5_error_code ret;
- krb5_data outbuf;
- krb5_keyblock *key_block;
- char *name;
- krb5_principal server;
- int zero = 0;
-
- if (cnt-- < 1)
- return;
- switch (*data++) {
- case KRB_AUTH:
- auth.data = (char *)data;
- auth.length = cnt;
-
- auth_context = NULL;
-
- ret = krb5_auth_con_init (context, &auth_context);
- if (ret) {
- Data(ap, KRB_REJECT, "krb5_auth_con_init failed", -1);
- auth_finished(ap, AUTH_REJECT);
- if (auth_debug_mode)
- printf("Kerberos V5: krb5_auth_con_init failed (%s)\r\n",
- krb5_get_err_text(context, ret));
- return;
- }
-
- ret = krb5_auth_con_setaddrs_from_fd (context,
- auth_context,
- &zero);
- if (ret) {
- Data(ap, KRB_REJECT, "krb5_auth_con_setaddrs_from_fd failed", -1);
- auth_finished(ap, AUTH_REJECT);
- if (auth_debug_mode)
- printf("Kerberos V5: "
- "krb5_auth_con_setaddrs_from_fd failed (%s)\r\n",
- krb5_get_err_text(context, ret));
- return;
- }
-
- ret = krb5_sock_to_principal (context,
- 0,
- "host",
- KRB5_NT_SRV_HST,
- &server);
- if (ret) {
- Data(ap, KRB_REJECT, "krb5_sock_to_principal failed", -1);
- auth_finished(ap, AUTH_REJECT);
- if (auth_debug_mode)
- printf("Kerberos V5: "
- "krb5_sock_to_principal failed (%s)\r\n",
- krb5_get_err_text(context, ret));
- return;
- }
-
- ret = krb5_rd_req(context,
- &auth_context,
- &auth,
- server,
- NULL,
- NULL,
- &ticket);
-
- krb5_free_principal (context, server);
- if (ret) {
- char *errbuf;
-
- asprintf(&errbuf,
- "Read req failed: %s",
- krb5_get_err_text(context, ret));
- Data(ap, KRB_REJECT, errbuf, -1);
- if (auth_debug_mode)
- printf("%s\r\n", errbuf);
- free (errbuf);
- return;
- }
-
- {
- char foo[2];
-
- foo[0] = ap->type;
- foo[1] = ap->way;
-
- ret = krb5_verify_authenticator_checksum(context,
- auth_context,
- foo,
- sizeof(foo));
-
- if (ret) {
- char *errbuf;
- asprintf(&errbuf, "Bad checksum: %s",
- krb5_get_err_text(context, ret));
- Data(ap, KRB_REJECT, errbuf, -1);
- if (auth_debug_mode)
- printf ("%s\r\n", errbuf);
- free(errbuf);
- return;
- }
- }
- ret = krb5_auth_con_getremotesubkey (context,
- auth_context,
- &key_block);
-
- if (ret) {
- Data(ap, KRB_REJECT, "krb5_auth_con_getremotesubkey failed", -1);
- auth_finished(ap, AUTH_REJECT);
- if (auth_debug_mode)
- printf("Kerberos V5: "
- "krb5_auth_con_getremotesubkey failed (%s)\r\n",
- krb5_get_err_text(context, ret));
- return;
- }
-
- if (key_block == NULL) {
- ret = krb5_auth_con_getkey(context,
- auth_context,
- &key_block);
- }
- if (ret) {
- Data(ap, KRB_REJECT, "krb5_auth_con_getkey failed", -1);
- auth_finished(ap, AUTH_REJECT);
- if (auth_debug_mode)
- printf("Kerberos V5: "
- "krb5_auth_con_getkey failed (%s)\r\n",
- krb5_get_err_text(context, ret));
- return;
- }
- if (key_block == NULL) {
- Data(ap, KRB_REJECT, "no subkey received", -1);
- auth_finished(ap, AUTH_REJECT);
- if (auth_debug_mode)
- printf("Kerberos V5: "
- "krb5_auth_con_getremotesubkey returned NULL key\r\n");
- return;
- }
-
- if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- ret = krb5_mk_rep(context, auth_context, &outbuf);
- if (ret) {
- Data(ap, KRB_REJECT,
- "krb5_mk_rep failed", -1);
- auth_finished(ap, AUTH_REJECT);
- if (auth_debug_mode)
- printf("Kerberos V5: "
- "krb5_mk_rep failed (%s)\r\n",
- krb5_get_err_text(context, ret));
- return;
- }
- Data(ap, KRB_RESPONSE, outbuf.data, outbuf.length);
- }
- if (krb5_unparse_name(context, ticket->client, &name))
- name = 0;
-
- if(UserNameRequested && krb5_kuserok(context,
- ticket->client,
- UserNameRequested)) {
- Data(ap, KRB_ACCEPT, name, name ? -1 : 0);
- if (auth_debug_mode) {
- printf("Kerberos5 identifies him as ``%s''\r\n",
- name ? name : "");
- }
-
- if(key_block->keytype == ETYPE_DES_CBC_MD5 ||
- key_block->keytype == ETYPE_DES_CBC_MD4 ||
- key_block->keytype == ETYPE_DES_CBC_CRC) {
- Session_Key skey;
-
- skey.type = SK_DES;
- skey.length = 8;
- skey.data = key_block->keyvalue.data;
- encrypt_session_key(&skey, 0);
- }
-
- } else {
- char *msg;
-
- asprintf (&msg, "user `%s' is not authorized to "
- "login as `%s'",
- name ? name : "<unknown>",
- UserNameRequested ? UserNameRequested : "<nobody>");
- if (msg == NULL)
- Data(ap, KRB_REJECT, NULL, 0);
- else {
- Data(ap, KRB_REJECT, (void *)msg, -1);
- free(msg);
- }
- auth_finished (ap, AUTH_REJECT);
- krb5_free_keyblock_contents(context, key_block);
- break;
- }
- auth_finished(ap, AUTH_USER);
- krb5_free_keyblock_contents(context, key_block);
-
- break;
- case KRB_FORWARD: {
- struct passwd *pwd;
- char ccname[1024]; /* XXX */
- krb5_data inbuf;
- krb5_ccache ccache;
- inbuf.data = (char *)data;
- inbuf.length = cnt;
-
- pwd = getpwnam (UserNameRequested);
- if (pwd == NULL)
- break;
-
- snprintf (ccname, sizeof(ccname),
- "FILE:/tmp/krb5cc_%u", pwd->pw_uid);
-
- ret = krb5_cc_resolve (context, ccname, &ccache);
- if (ret) {
- if (auth_debug_mode)
- printf ("Kerberos V5: could not get ccache: %s\r\n",
- krb5_get_err_text(context, ret));
- break;
- }
-
- ret = krb5_cc_initialize (context,
- ccache,
- ticket->client);
- if (ret) {
- if (auth_debug_mode)
- printf ("Kerberos V5: could not init ccache: %s\r\n",
- krb5_get_err_text(context, ret));
- break;
- }
-
-#if defined(DCE)
- esetenv("KRB5CCNAME", ccname, 1);
-#endif
- ret = krb5_rd_cred2 (context,
- auth_context,
- ccache,
- &inbuf);
- if(ret) {
- char *errbuf;
-
- asprintf (&errbuf,
- "Read forwarded creds failed: %s",
- krb5_get_err_text (context, ret));
- if(errbuf == NULL)
- Data(ap, KRB_FORWARD_REJECT, NULL, 0);
- else
- Data(ap, KRB_FORWARD_REJECT, errbuf, -1);
- if (auth_debug_mode)
- printf("Could not read forwarded credentials: %s\r\n",
- errbuf);
- free (errbuf);
- } else {
- Data(ap, KRB_FORWARD_ACCEPT, 0, 0);
-#if defined(DCE)
- dfsfwd = 1;
-#endif
- }
- chown (ccname + 5, pwd->pw_uid, -1);
- if (auth_debug_mode)
- printf("Forwarded credentials obtained\r\n");
- break;
- }
- default:
- if (auth_debug_mode)
- printf("Unknown Kerberos option %d\r\n", data[-1]);
- Data(ap, KRB_REJECT, 0, 0);
- break;
- }
-}
-
-void
-kerberos5_reply(Authenticator *ap, unsigned char *data, int cnt)
-{
- static int mutual_complete = 0;
-
- if (cnt-- < 1)
- return;
- switch (*data++) {
- case KRB_REJECT:
- if (cnt > 0) {
- printf("[ Kerberos V5 refuses authentication because %.*s ]\r\n",
- cnt, data);
- } else
- printf("[ Kerberos V5 refuses authentication ]\r\n");
- auth_send_retry();
- return;
- case KRB_ACCEPT: {
- krb5_error_code ret;
- Session_Key skey;
- krb5_keyblock *keyblock;
-
- if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
- !mutual_complete) {
- printf("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\r\n");
- auth_send_retry();
- return;
- }
- if (cnt)
- printf("[ Kerberos V5 accepts you as ``%.*s'' ]\r\n", cnt, data);
- else
- printf("[ Kerberos V5 accepts you ]\r\n");
-
- ret = krb5_auth_con_getlocalsubkey (context,
- auth_context,
- &keyblock);
- if (ret)
- ret = krb5_auth_con_getkey (context,
- auth_context,
- &keyblock);
- if(ret) {
- printf("[ krb5_auth_con_getkey: %s ]\r\n",
- krb5_get_err_text(context, ret));
- auth_send_retry();
- return;
- }
-
- skey.type = SK_DES;
- skey.length = 8;
- skey.data = keyblock->keyvalue.data;
- encrypt_session_key(&skey, 0);
- krb5_free_keyblock_contents (context, keyblock);
- auth_finished(ap, AUTH_USER);
- if (forward_flags & OPTS_FORWARD_CREDS)
- kerberos5_forward(ap);
- break;
- }
- case KRB_RESPONSE:
- if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- /* the rest of the reply should contain a krb_ap_rep */
- krb5_ap_rep_enc_part *reply;
- krb5_data inbuf;
- krb5_error_code ret;
-
- inbuf.length = cnt;
- inbuf.data = (char *)data;
-
- ret = krb5_rd_rep(context, auth_context, &inbuf, &reply);
- if (ret) {
- printf("[ Mutual authentication failed: %s ]\r\n",
- krb5_get_err_text (context, ret));
- auth_send_retry();
- return;
- }
- krb5_free_ap_rep_enc_part(context, reply);
- mutual_complete = 1;
- }
- return;
- case KRB_FORWARD_ACCEPT:
- printf("[ Kerberos V5 accepted forwarded credentials ]\r\n");
- return;
- case KRB_FORWARD_REJECT:
- printf("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n",
- cnt, data);
- return;
- default:
- if (auth_debug_mode)
- printf("Unknown Kerberos option %d\r\n", data[-1]);
- return;
- }
-}
-
-int
-kerberos5_status(Authenticator *ap, char *name, size_t name_sz, int level)
-{
- if (level < AUTH_USER)
- return(level);
-
- if (UserNameRequested &&
- krb5_kuserok(context,
- ticket->client,
- UserNameRequested))
- {
- strlcpy(name, UserNameRequested, name_sz);
-#if defined(DCE)
- dfsk5ok = 1;
-#endif
- return(AUTH_VALID);
- } else
- return(AUTH_USER);
-}
-
-#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
-#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
-
-void
-kerberos5_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
-{
- int i;
-
- buf[buflen-1] = '\0'; /* make sure its NULL terminated */
- buflen -= 1;
-
- switch(data[3]) {
- case KRB_REJECT: /* Rejected (reason might follow) */
- strlcpy((char *)buf, " REJECT ", buflen);
- goto common;
-
- case KRB_ACCEPT: /* Accepted (name might follow) */
- strlcpy((char *)buf, " ACCEPT ", buflen);
- common:
- BUMP(buf, buflen);
- if (cnt <= 4)
- break;
- ADDC(buf, buflen, '"');
- for (i = 4; i < cnt; i++)
- ADDC(buf, buflen, data[i]);
- ADDC(buf, buflen, '"');
- ADDC(buf, buflen, '\0');
- break;
-
-
- case KRB_AUTH: /* Authentication data follows */
- strlcpy((char *)buf, " AUTH", buflen);
- goto common2;
-
- case KRB_RESPONSE:
- strlcpy((char *)buf, " RESPONSE", buflen);
- goto common2;
-
- case KRB_FORWARD: /* Forwarded credentials follow */
- strlcpy((char *)buf, " FORWARD", buflen);
- goto common2;
-
- case KRB_FORWARD_ACCEPT: /* Forwarded credentials accepted */
- strlcpy((char *)buf, " FORWARD_ACCEPT", buflen);
- goto common2;
-
- case KRB_FORWARD_REJECT: /* Forwarded credentials rejected */
- /* (reason might follow) */
- strlcpy((char *)buf, " FORWARD_REJECT", buflen);
- goto common2;
-
- default:
- snprintf(buf, buflen, " %d (unknown)", data[3]);
- common2:
- BUMP(buf, buflen);
- for (i = 4; i < cnt; i++) {
- snprintf(buf, buflen, " %d", data[i]);
- BUMP(buf, buflen);
- }
- break;
- }
-}
-
-void
-kerberos5_forward(Authenticator *ap)
-{
- krb5_error_code ret;
- krb5_ccache ccache;
- krb5_creds creds;
- krb5_kdc_flags flags;
- krb5_data out_data;
- krb5_principal principal;
-
- ret = krb5_cc_default (context, &ccache);
- if (ret) {
- if (auth_debug_mode)
- printf ("KerberosV5: could not get default ccache: %s\r\n",
- krb5_get_err_text (context, ret));
- return;
- }
-
- ret = krb5_cc_get_principal (context, ccache, &principal);
- if (ret) {
- if (auth_debug_mode)
- printf ("KerberosV5: could not get principal: %s\r\n",
- krb5_get_err_text (context, ret));
- return;
- }
-
- memset (&creds, 0, sizeof(creds));
-
- creds.client = principal;
-
- ret = krb5_build_principal (context,
- &creds.server,
- strlen(principal->realm),
- principal->realm,
- "krbtgt",
- principal->realm,
- NULL);
-
- if (ret) {
- if (auth_debug_mode)
- printf ("KerberosV5: could not get principal: %s\r\n",
- krb5_get_err_text (context, ret));
- return;
- }
-
- creds.times.endtime = 0;
-
- flags.i = 0;
- flags.b.forwarded = 1;
- if (forward_flags & OPTS_FORWARDABLE_CREDS)
- flags.b.forwardable = 1;
-
- ret = krb5_get_forwarded_creds (context,
- auth_context,
- ccache,
- flags.i,
- RemoteHostName,
- &creds,
- &out_data);
- if (ret) {
- if (auth_debug_mode)
- printf ("Kerberos V5: error getting forwarded creds: %s\r\n",
- krb5_get_err_text (context, ret));
- return;
- }
-
- if(!Data(ap, KRB_FORWARD, out_data.data, out_data.length)) {
- if (auth_debug_mode)
- printf("Not enough room for authentication data\r\n");
- } else {
- if (auth_debug_mode)
- printf("Forwarded local Kerberos V5 credentials to server\r\n");
- }
-}
-
-#if defined(DCE)
-/* if this was a K5 authentication try and join a PAG for the user. */
-void
-kerberos5_dfspag(void)
-{
- if (dfsk5ok) {
- dfspag = krb5_dfs_pag(context, dfsfwd, ticket->client,
- UserNameRequested);
- }
-}
-#endif
-
-int
-kerberos5_set_forward(int on)
-{
- if(on == 0)
- forward_flags &= ~OPTS_FORWARD_CREDS;
- if(on == 1)
- forward_flags |= OPTS_FORWARD_CREDS;
- if(on == -1)
- forward_flags ^= OPTS_FORWARD_CREDS;
- return 0;
-}
-
-int
-kerberos5_set_forwardable(int on)
-{
- if(on == 0)
- forward_flags &= ~OPTS_FORWARDABLE_CREDS;
- if(on == 1)
- forward_flags |= OPTS_FORWARDABLE_CREDS;
- if(on == -1)
- forward_flags ^= OPTS_FORWARDABLE_CREDS;
- return 0;
-}
-
-#endif /* KRB5 */
diff --git a/libexec/telnetd/mini_inetd.c b/libexec/telnetd/mini_inetd.c
deleted file mode 100644
index a240e306f13..00000000000
--- a/libexec/telnetd/mini_inetd.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-RCSID("$KTH: mini_inetd.c,v 1.28 2000/10/08 13:38:47 assar Exp $");
-#endif
-
-#include "telnetd.h"
-
-#include <err.h>
-
-#ifndef max
-#define max(a,b) (((a)>(b))?(a):(b))
-#endif
-
-/*
- * accept a connection on `s' and pretend it's served by inetd.
- */
-
-static void
-accept_it (int s)
-{
- int s2;
-
- s2 = accept(s, NULL, NULL);
- if(s2 < 0)
- err (1, "accept");
- close(s);
- dup2(s2, STDIN_FILENO);
- dup2(s2, STDOUT_FILENO);
- /* dup2(s2, STDERR_FILENO); */
- close(s2);
-}
-
-/*
- * Listen on `port' emulating inetd.
- */
-
-void
-mini_inetd (int port)
-{
- int error, ret;
- struct addrinfo *ai, *a, hints;
- char portstr[NI_MAXSERV];
- int n, nalloc, i;
- int *fds;
- fd_set orig_read_set, read_set;
- int max_fd = -1;
-
- memset (&hints, 0, sizeof(hints));
- hints.ai_flags = AI_PASSIVE;
- hints.ai_socktype = SOCK_STREAM;
-
- snprintf (portstr, sizeof(portstr), "%d", ntohs(port));
-
- error = getaddrinfo (NULL, portstr, &hints, &ai);
- if (error)
- errx (1, "getaddrinfo: %s", gai_strerror (error));
-
- for (nalloc = 0, a = ai; a != NULL; a = a->ai_next)
- ++nalloc;
-
- fds = malloc (nalloc * sizeof(*fds));
- if (fds == NULL)
- errx (1, "mini_inetd: out of memory");
-
- FD_ZERO(&orig_read_set);
-
- for (i = 0, a = ai; a != NULL; a = a->ai_next) {
- fds[i] = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
- if (fds[i] < 0) {
- warn ("socket");
- continue;
- }
- socket_set_reuseaddr (fds[i], 1);
- if (bind (fds[i], a->ai_addr, a->ai_addrlen) < 0)
- err (1, "bind");
- if (listen (fds[i], SOMAXCONN) < 0)
- err (1, "listen");
- if (fds[i] >= FD_SETSIZE)
- errx (1, "fd too large");
- FD_SET(fds[i], &orig_read_set);
- max_fd = max(max_fd, fds[i]);
- ++i;
- }
- freeaddrinfo (ai);
- if (i == 0)
- errx (1, "no sockets");
- n = i;
-
- do {
- read_set = orig_read_set;
-
- ret = select (max_fd + 1, &read_set, NULL, NULL, NULL);
- if (ret < 0 && errno != EINTR)
- err (1, "select");
- } while (ret <= 0);
-
- for (i = 0; i < n; ++i)
- if (FD_ISSET (fds[i], &read_set)) {
- accept_it (fds[i]);
- return;
- }
- abort ();
-}
diff --git a/libexec/telnetd/misc-proto.h b/libexec/telnetd/misc-proto.h
deleted file mode 100644
index 978e3b8446a..00000000000
--- a/libexec/telnetd/misc-proto.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*-
- * 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.
- *
- * from: @(#)misc-proto.h 8.1 (Berkeley) 6/4/93
- * $OpenBSD: misc-proto.h,v 1.2 2003/06/02 19:38:25 millert Exp $
- * $NetBSD: misc-proto.h,v 1.5 1996/02/24 01:15:23 jtk Exp $
- */
-
-/*
- * This source code is no longer held under any constraint of USA
- * `cryptographic laws' since it was exported legally. The cryptographic
- * functions were removed from the code and a "Bones" distribution was
- * made. A Commodity Jurisdiction Request #012-94 was filed with the
- * USA State Department, who handed it to the Commerce department. The
- * code was determined to fall under General License GTDA under ECCN 5D96G,
- * and hence exportable. The cryptographic interfaces were re-added by Eric
- * Young, and then KTH proceeded to maintain the code in the free world.
- *
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America is assumed
- * to require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-/* $KTH: misc-proto.h,v 1.9 2000/11/15 23:00:21 assar Exp $ */
-
-#ifndef __MISC_PROTO__
-#define __MISC_PROTO__
-
-void auth_encrypt_init (const char *, const char *, const char *, int);
-void auth_encrypt_user(const char *name);
-void auth_encrypt_connect (int);
-void printd (const unsigned char *, int);
-
-char** genget (char *name, char **table, int stlen);
-int isprefix(char *s1, char *s2);
-int Ambiguous(void *s);
-
-/*
- * These functions are imported from the application
- */
-int telnet_net_write (unsigned char *, int);
-void net_encrypt (void);
-int telnet_spin (void);
-char *telnet_getenv (const char *);
-char *telnet_gets (char *, char *, int, int);
-void printsub(int direction, unsigned char *pointer, int length);
-void esetenv(const char *, const char *, int);
-#endif
diff --git a/libexec/telnetd/misc.c b/libexec/telnetd/misc.c
deleted file mode 100644
index 69b049c6302..00000000000
--- a/libexec/telnetd/misc.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*-
- * 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.
- */
-
-#ifndef lint
-/* from: static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/4/93"; */
-/* from: static char rcsid[] = "$NetBSD: misc.c,v 1.5 1996/02/24 01:15:25 jtk Exp $"; */
-static char rcsid[] = "$OpenBSD: misc.c,v 1.2 2003/06/02 19:38:25 millert Exp $";
-#endif /* not lint */
-
-/* $KTH: misc.c,v 1.15 2000/01/25 23:24:58 assar Exp $ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <err.h>
-#include "misc.h"
-#include "auth.h"
-#include "encrypt.h"
-
-
-const char *RemoteHostName;
-const char *LocalHostName;
-char *UserNameRequested = 0;
-int ConnectedCount = 0;
-
-void
-auth_encrypt_init(const char *local, const char *remote, const char *name,
- int server)
-{
- RemoteHostName = remote;
- LocalHostName = local;
-#ifdef AUTHENTICATION
- auth_init(name, server);
-#endif
-#ifdef ENCRYPTION
- encrypt_init(name, server);
-#endif
- if (UserNameRequested) {
- free(UserNameRequested);
- UserNameRequested = 0;
- }
-}
-
-void
-auth_encrypt_user(const char *name)
-{
- if (UserNameRequested)
- free(UserNameRequested);
- UserNameRequested = name ? strdup(name) : 0;
-}
-
-void
-auth_encrypt_connect(int cnt)
-{
-}
-
-void
-printd(const unsigned char *data, int cnt)
-{
- if (cnt > 16)
- cnt = 16;
- while (cnt-- > 0) {
- printf(" %02x", *data);
- ++data;
- }
-}
-
-/* This is stolen from libroken; it's the only thing actually needed from
- * libroken.
- */
-void
-esetenv(const char *var, const char *val, int rewrite)
-{
- if (setenv ((char *)var, (char *)val, rewrite))
- errx (1, "failed setting environment variable %s", var);
-}
diff --git a/libexec/telnetd/misc.h b/libexec/telnetd/misc.h
deleted file mode 100644
index f98e78ad23d..00000000000
--- a/libexec/telnetd/misc.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*-
- * 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.
- *
- * from: @(#)misc.h 8.1 (Berkeley) 6/4/93
- * $OpenBSD: misc.h,v 1.2 2003/06/02 19:38:25 millert Exp $
- * $NetBSD: misc.h,v 1.4 1996/02/24 01:15:27 jtk Exp $
- */
-
-extern char *UserNameRequested;
-extern const char *LocalHostName;
-extern const char *RemoteHostName;
-extern int ConnectedCount;
-extern int ReservedPort;
-
-#include "misc-proto.h"
diff --git a/libexec/telnetd/slc.c b/libexec/telnetd/slc.c
deleted file mode 100644
index ea82b3373ec..00000000000
--- a/libexec/telnetd/slc.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 "telnetd.h"
-
-/* RCSID("$KTH: slc.c,v 1.10 1997/05/11 06:30:00 assar Exp $"); */
-
-/*
- * 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;
- }
-
-}
diff --git a/libexec/telnetd/socket.c b/libexec/telnetd/socket.c
deleted file mode 100644
index ef0ecee692b..00000000000
--- a/libexec/telnetd/socket.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-RCSID("$KTH: socket.c,v 1.5 2000/07/27 04:41:06 assar Exp $");
-#endif
-
-#include <telnetd.h>
-#include <err.h>
-#include <netinet/in.h>
-
-/*
- * set the reuse of addresses on `sock' to `val'.
- */
-
-void
-socket_set_reuseaddr (int sock, int val)
-{
-#if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT)
- if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val,
- sizeof(val)) < 0)
- err (1, "setsockopt SO_REUSEADDR");
-#endif
-}
diff --git a/libexec/telnetd/state.c b/libexec/telnetd/state.c
deleted file mode 100644
index 2daab2c4600..00000000000
--- a/libexec/telnetd/state.c
+++ /dev/null
@@ -1,1400 +0,0 @@
-/*
- * 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 "telnetd.h"
-#include <syslog.h>
-
-/* RCSID("$KTH: state.c,v 1.14 2000/10/02 05:06:02 assar Exp $"); */
-
-unsigned char doopt[] = { IAC, DO, '%', 'c', 0 };
-unsigned char dont[] = { IAC, DONT, '%', 'c', 0 };
-unsigned char will[] = { IAC, WILL, '%', 'c', 0 };
-unsigned char wont[] = { IAC, WONT, '%', 'c', 0 };
-int not42 = 1;
-
-/*
- * Buffer for sub-options, and macros
- * for suboptions buffer manipulations
- */
-unsigned char subbuffer[2048], *subpointer= subbuffer, *subend= subbuffer;
-
-#define SB_CLEAR() subpointer = subbuffer
-#define SB_TERM() { subend = subpointer; SB_CLEAR(); }
-#define SB_ACCUM(c) if (subpointer < (subbuffer+sizeof subbuffer)) { \
- *subpointer++ = (c); \
- }
-#define SB_GET() ((*subpointer++)&0xff)
-#define SB_EOF() (subpointer >= subend)
-#define SB_LEN() (subend - subpointer)
-
-#ifdef ENV_HACK
-unsigned char *subsave;
-#define SB_SAVE() subsave = subpointer;
-#define SB_RESTORE() subpointer = subsave;
-#endif
-
-
-/*
- * State for recv fsm
- */
-#define TS_DATA 0 /* base state */
-#define TS_IAC 1 /* look for double IAC's */
-#define TS_CR 2 /* CR-LF ->'s CR */
-#define TS_SB 3 /* throw away begin's... */
-#define TS_SE 4 /* ...end's (suboption negotiation) */
-#define TS_WILL 5 /* will option negotiation */
-#define TS_WONT 6 /* wont -''- */
-#define TS_DO 7 /* do -''- */
-#define TS_DONT 8 /* dont -''- */
-
-void
-telrcv(void)
-{
- int c;
- static int state = TS_DATA;
-
- while (ncc > 0) {
- if ((&ptyobuf[BUFSIZ] - pfrontp) < 2)
- break;
- c = *netip++ & 0377, ncc--;
-#ifdef ENCRYPTION
- if (decrypt_input)
- c = (*decrypt_input)(c);
-#endif
- switch (state) {
-
- case TS_CR:
- state = TS_DATA;
- /* Strip off \n or \0 after a \r */
- if ((c == 0) || (c == '\n')) {
- break;
- }
- /* FALL THROUGH */
-
- case TS_DATA:
- if (c == IAC) {
- state = TS_IAC;
- break;
- }
- /*
- * We now map \r\n ==> \r for pragmatic reasons.
- * Many client implementations send \r\n when
- * the user hits the CarriageReturn key.
- *
- * We USED to map \r\n ==> \n, since \r\n says
- * that we want to be in column 1 of the next
- * printable line, and \n is the standard
- * unix way of saying that (\r is only good
- * if CRMOD is set, which it normally is).
- */
- if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) {
-#ifdef ENCRYPTION
- int nc = *netip;
-
- if (decrypt_input)
- nc = (*decrypt_input)(nc & 0xff);
-#endif
- {
-#ifdef ENCRYPTION
- if (decrypt_input)
- (void)(*decrypt_input)(-1);
-#endif
- state = TS_CR;
- }
- }
- *pfrontp++ = c;
- break;
-
- case TS_IAC:
- gotiac: switch (c) {
-
- /*
- * Send the process on the pty side an
- * interrupt. Do this with a NULL or
- * interrupt char; depending on the tty mode.
- */
- case IP:
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- interrupt();
- break;
-
- case BREAK:
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- sendbrk();
- break;
-
- /*
- * Are You There?
- */
- case AYT:
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- recv_ayt();
- break;
-
- /*
- * Abort Output
- */
- case AO:
- {
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- ptyflush(); /* half-hearted */
- init_termbuf();
-
- if (slctab[SLC_AO].sptr &&
- *slctab[SLC_AO].sptr != (cc_t)(_POSIX_VDISABLE)) {
- *pfrontp++ =
- (unsigned char)*slctab[SLC_AO].sptr;
- }
-
- netclear(); /* clear buffer back */
- output_data ("%c%c", IAC, DM);
- neturg = nfrontp-1; /* off by one XXX */
- DIAG(TD_OPTIONS,
- printoption("td: send IAC", DM));
- break;
- }
-
- /*
- * Erase Character and
- * Erase Line
- */
- case EC:
- case EL:
- {
- cc_t ch;
-
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- ptyflush(); /* half-hearted */
- init_termbuf();
- if (c == EC)
- ch = *slctab[SLC_EC].sptr;
- else
- ch = *slctab[SLC_EL].sptr;
- if (ch != (cc_t)(_POSIX_VDISABLE))
- *pfrontp++ = (unsigned char)ch;
- break;
- }
-
- /*
- * Check for urgent data...
- */
- case DM:
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- SYNCHing = stilloob(net);
- settimer(gotDM);
- break;
-
-
- /*
- * Begin option subnegotiation...
- */
- case SB:
- state = TS_SB;
- SB_CLEAR();
- continue;
-
- case WILL:
- state = TS_WILL;
- continue;
-
- case WONT:
- state = TS_WONT;
- continue;
-
- case DO:
- state = TS_DO;
- continue;
-
- case DONT:
- state = TS_DONT;
- continue;
- case EOR:
- if (his_state_is_will(TELOPT_EOR))
- doeof();
- break;
-
- /*
- * Handle RFC 10xx Telnet linemode option additions
- * to command stream (EOF, SUSP, ABORT).
- */
- case xEOF:
- doeof();
- break;
-
- case SUSP:
- sendsusp();
- break;
-
- case ABORT:
- sendbrk();
- break;
-
- case IAC:
- *pfrontp++ = c;
- break;
- }
- state = TS_DATA;
- break;
-
- case TS_SB:
- if (c == IAC) {
- state = TS_SE;
- } else {
- SB_ACCUM(c);
- }
- break;
-
- case TS_SE:
- if (c != SE) {
- if (c != IAC) {
- /*
- * bad form of suboption negotiation.
- * handle it in such a way as to avoid
- * damage to local state. Parse
- * suboption buffer found so far,
- * then treat remaining stream as
- * another command sequence.
- */
-
- /* for DIAGNOSTICS */
- SB_ACCUM(IAC);
- SB_ACCUM(c);
- subpointer -= 2;
-
- SB_TERM();
- suboption();
- state = TS_IAC;
- goto gotiac;
- }
- SB_ACCUM(c);
- state = TS_SB;
- } else {
- /* for DIAGNOSTICS */
- SB_ACCUM(IAC);
- SB_ACCUM(SE);
- subpointer -= 2;
-
- SB_TERM();
- suboption(); /* handle sub-option */
- state = TS_DATA;
- }
- break;
-
- case TS_WILL:
- willoption(c);
- state = TS_DATA;
- continue;
-
- case TS_WONT:
- wontoption(c);
- if (c==TELOPT_ENCRYPT && his_do_dont_is_changing(TELOPT_ENCRYPT) )
- dontoption(c);
- state = TS_DATA;
- continue;
-
- case TS_DO:
- dooption(c);
- state = TS_DATA;
- continue;
-
- case TS_DONT:
- dontoption(c);
- state = TS_DATA;
- continue;
-
- default:
- syslog(LOG_ERR, "telnetd: panic state=%d", state);
- printf("telnetd: panic state=%d\n", state);
- exit(1);
- }
- }
-} /* end of telrcv */
-
-/*
- * The will/wont/do/dont state machines are based on Dave Borman's
- * Telnet option processing state machine.
- *
- * These correspond to the following states:
- * my_state = the last negotiated state
- * want_state = what I want the state to go to
- * want_resp = how many requests I have sent
- * All state defaults are negative, and resp defaults to 0.
- *
- * When initiating a request to change state to new_state:
- *
- * if ((want_resp == 0 && new_state == my_state) || want_state == new_state) {
- * do nothing;
- * } else {
- * want_state = new_state;
- * send new_state;
- * want_resp++;
- * }
- *
- * When receiving new_state:
- *
- * if (want_resp) {
- * want_resp--;
- * if (want_resp && (new_state == my_state))
- * want_resp--;
- * }
- * if ((want_resp == 0) && (new_state != want_state)) {
- * if (ok_to_switch_to new_state)
- * want_state = new_state;
- * else
- * want_resp++;
- * send want_state;
- * }
- * my_state = new_state;
- *
- * Note that new_state is implied in these functions by the function itself.
- * will and do imply positive new_state, wont and dont imply negative.
- *
- * Finally, there is one catch. If we send a negative response to a
- * positive request, my_state will be the positive while want_state will
- * remain negative. my_state will revert to negative when the negative
- * acknowlegment arrives from the peer. Thus, my_state generally tells
- * us not only the last negotiated state, but also tells us what the peer
- * wants to be doing as well. It is important to understand this difference
- * as we may wish to be processing data streams based on our desired state
- * (want_state) or based on what the peer thinks the state is (my_state).
- *
- * This all works fine because if the peer sends a positive request, the data
- * that we receive prior to negative acknowlegment will probably be affected
- * by the positive state, and we can process it as such (if we can; if we
- * can't then it really doesn't matter). If it is that important, then the
- * peer probably should be buffering until this option state negotiation
- * is complete.
- *
- */
-void
-send_do(int option, int init)
-{
- if (init) {
- if ((do_dont_resp[option] == 0 && his_state_is_will(option)) ||
- his_want_state_is_will(option))
- return;
- /*
- * Special case for TELOPT_TM: We send a DO, but pretend
- * that we sent a DONT, so that we can send more DOs if
- * we want to.
- */
- if (option == TELOPT_TM)
- set_his_want_state_wont(option);
- else
- set_his_want_state_will(option);
- do_dont_resp[option]++;
- }
- output_data((const char *)doopt, option);
-
- DIAG(TD_OPTIONS, printoption("td: send do", option));
-}
-
-#ifdef AUTHENTICATION
-extern void auth_request(void);
-#endif
-#ifdef ENCRYPTION
-extern void encrypt_send_support(void);
-#endif
-
-void
-willoption(int option)
-{
- int changeok = 0;
- void (*func)(void) = 0;
-
- /*
- * process input from peer.
- */
-
- DIAG(TD_OPTIONS, printoption("td: recv will", option));
-
- if (do_dont_resp[option]) {
- do_dont_resp[option]--;
- if (do_dont_resp[option] && his_state_is_will(option))
- do_dont_resp[option]--;
- }
- if (do_dont_resp[option] == 0) {
- if (his_want_state_is_wont(option)) {
- switch (option) {
-
- case TELOPT_BINARY:
- init_termbuf();
- tty_binaryin(1);
- set_termbuf();
- changeok++;
- break;
-
- case TELOPT_ECHO:
- /*
- * See comments below for more info.
- */
- not42 = 0; /* looks like a 4.2 system */
- break;
-
- case TELOPT_TM:
- /*
- * We never respond to a WILL TM, and
- * we leave the state WONT.
- */
- return;
-
- case TELOPT_LFLOW:
- /*
- * If we are going to support flow control
- * option, then don't worry peer that we can't
- * change the flow control characters.
- */
- slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS;
- slctab[SLC_XON].defset.flag |= SLC_DEFAULT;
- slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS;
- slctab[SLC_XOFF].defset.flag |= SLC_DEFAULT;
- case TELOPT_TTYPE:
- case TELOPT_SGA:
- case TELOPT_NAWS:
- case TELOPT_TSPEED:
- case TELOPT_XDISPLOC:
- case TELOPT_NEW_ENVIRON:
- case TELOPT_OLD_ENVIRON:
- changeok++;
- break;
-
-
-#ifdef AUTHENTICATION
- case TELOPT_AUTHENTICATION:
- func = auth_request;
- changeok++;
- break;
-#endif
-
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- func = encrypt_send_support;
- changeok++;
- break;
-#endif
-
- default:
- break;
- }
- if (changeok) {
- set_his_want_state_will(option);
- send_do(option, 0);
- } else {
- do_dont_resp[option]++;
- send_dont(option, 0);
- }
- } else {
- /*
- * Option processing that should happen when
- * we receive conformation of a change in
- * state that we had requested.
- */
- switch (option) {
- case TELOPT_ECHO:
- not42 = 0; /* looks like a 4.2 system */
- /*
- * Egads, he responded "WILL ECHO". Turn
- * it off right now!
- */
- send_dont(option, 1);
- /*
- * "WILL ECHO". Kludge upon kludge!
- * A 4.2 client is now echoing user input at
- * the tty. This is probably undesireable and
- * it should be stopped. The client will
- * respond WONT TM to the DO TM that we send to
- * check for kludge linemode. When the WONT TM
- * arrives, linemode will be turned off and a
- * change propogated to the pty. This change
- * will cause us to process the new pty state
- * in localstat(), which will notice that
- * linemode is off and send a WILL ECHO
- * so that we are properly in character mode and
- * all is well.
- */
- break;
-
-#ifdef AUTHENTICATION
- case TELOPT_AUTHENTICATION:
- func = auth_request;
- break;
-#endif
-
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- func = encrypt_send_support;
- break;
-#endif
-
- case TELOPT_LFLOW:
- func = flowstat;
- break;
- }
- }
- }
- set_his_state_will(option);
- if (func)
- (*func)();
-} /* end of willoption */
-
-void
-send_dont(int option, int init)
-{
- if (init) {
- if ((do_dont_resp[option] == 0 && his_state_is_wont(option)) ||
- his_want_state_is_wont(option))
- return;
- set_his_want_state_wont(option);
- do_dont_resp[option]++;
- }
- output_data((const char *)dont, option);
-
- DIAG(TD_OPTIONS, printoption("td: send dont", option));
-}
-
-void
-wontoption(int option)
-{
- /*
- * Process client input.
- */
-
- DIAG(TD_OPTIONS, printoption("td: recv wont", option));
-
- if (do_dont_resp[option]) {
- do_dont_resp[option]--;
- if (do_dont_resp[option] && his_state_is_wont(option))
- do_dont_resp[option]--;
- }
- if (do_dont_resp[option] == 0) {
- if (his_want_state_is_will(option)) {
- /* it is always ok to change to negative state */
- switch (option) {
- case TELOPT_ECHO:
- not42 = 1; /* doesn't seem to be a 4.2 system */
- break;
-
- case TELOPT_BINARY:
- init_termbuf();
- tty_binaryin(0);
- set_termbuf();
- break;
-
- case TELOPT_TM:
- /*
- * If we get a WONT TM, and had sent a DO TM,
- * don't respond with a DONT TM, just leave it
- * as is. Short circut the state machine to
- * achive this.
- */
- set_his_want_state_wont(TELOPT_TM);
- return;
-
- case TELOPT_LFLOW:
- /*
- * If we are not going to support flow control
- * option, then let peer know that we can't
- * change the flow control characters.
- */
- slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS;
- slctab[SLC_XON].defset.flag |= SLC_CANTCHANGE;
- slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS;
- slctab[SLC_XOFF].defset.flag |= SLC_CANTCHANGE;
- break;
-
-#ifdef AUTHENTICATION
- case TELOPT_AUTHENTICATION:
- auth_finished(0, AUTH_REJECT);
- break;
-#endif
-
- /*
- * For options that we might spin waiting for
- * sub-negotiation, if the client turns off the
- * option rather than responding to the request,
- * we have to treat it here as if we got a response
- * to the sub-negotiation, (by updating the timers)
- * so that we'll break out of the loop.
- */
- case TELOPT_TTYPE:
- settimer(ttypesubopt);
- break;
-
- case TELOPT_TSPEED:
- settimer(tspeedsubopt);
- break;
-
- case TELOPT_XDISPLOC:
- settimer(xdisplocsubopt);
- break;
-
- case TELOPT_OLD_ENVIRON:
- settimer(oenvironsubopt);
- break;
-
- case TELOPT_NEW_ENVIRON:
- settimer(environsubopt);
- break;
-
- default:
- break;
- }
- set_his_want_state_wont(option);
- if (his_state_is_will(option))
- send_dont(option, 0);
- } else {
- switch (option) {
- case TELOPT_TM:
- break;
-
-#ifdef AUTHENTICATION
- case TELOPT_AUTHENTICATION:
- auth_finished(0, AUTH_REJECT);
- break;
-#endif
- default:
- break;
- }
- }
- }
- set_his_state_wont(option);
-
-} /* end of wontoption */
-
-void
-send_will(int option, int init)
-{
- if (init) {
- if ((will_wont_resp[option] == 0 && my_state_is_will(option))||
- my_want_state_is_will(option))
- return;
- set_my_want_state_will(option);
- will_wont_resp[option]++;
- }
- output_data ((const char *)will, option);
-
- DIAG(TD_OPTIONS, printoption("td: send will", option));
-}
-
-/*
- * When we get a DONT SGA, we will try once to turn it
- * back on. If the other side responds DONT SGA, we
- * leave it at that. This is so that when we talk to
- * clients that understand KLUDGELINEMODE but not LINEMODE,
- * we'll keep them in char-at-a-time mode.
- */
-int turn_on_sga = 0;
-
-void
-dooption(int option)
-{
- int changeok = 0;
-
- /*
- * Process client input.
- */
-
- DIAG(TD_OPTIONS, printoption("td: recv do", option));
-
- if (will_wont_resp[option]) {
- will_wont_resp[option]--;
- if (will_wont_resp[option] && my_state_is_will(option))
- will_wont_resp[option]--;
- }
- if ((will_wont_resp[option] == 0) && (my_want_state_is_wont(option))) {
- switch (option) {
- case TELOPT_ECHO:
- {
- init_termbuf();
- tty_setecho(1);
- set_termbuf();
- }
- changeok++;
- break;
-
- case TELOPT_BINARY:
- init_termbuf();
- tty_binaryout(1);
- set_termbuf();
- changeok++;
- break;
-
- case TELOPT_SGA:
- turn_on_sga = 0;
- changeok++;
- break;
-
- case TELOPT_STATUS:
- changeok++;
- break;
-
- case TELOPT_TM:
- /*
- * Special case for TM. We send a WILL, but
- * pretend we sent a WONT.
- */
- send_will(option, 0);
- set_my_want_state_wont(option);
- set_my_state_wont(option);
- return;
-
- case TELOPT_LOGOUT:
- /*
- * When we get a LOGOUT option, respond
- * with a WILL LOGOUT, make sure that
- * it gets written out to the network,
- * and then just go away...
- */
- set_my_want_state_will(TELOPT_LOGOUT);
- send_will(TELOPT_LOGOUT, 0);
- set_my_state_will(TELOPT_LOGOUT);
- netflush();
- cleanup(0);
- /* NOT REACHED */
- break;
-
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- changeok++;
- break;
-#endif
- case TELOPT_LINEMODE:
- case TELOPT_TTYPE:
- case TELOPT_NAWS:
- case TELOPT_TSPEED:
- case TELOPT_LFLOW:
- case TELOPT_XDISPLOC:
-#ifdef TELOPT_ENVIRON
- case TELOPT_NEW_ENVIRON:
-#endif
- case TELOPT_OLD_ENVIRON:
- default:
- break;
- }
- if (changeok) {
- set_my_want_state_will(option);
- send_will(option, 0);
- } else {
- will_wont_resp[option]++;
- send_wont(option, 0);
- }
- }
- set_my_state_will(option);
-
-} /* end of dooption */
-
-void
-send_wont(int option, int init)
-{
- if (init) {
- if ((will_wont_resp[option] == 0 && my_state_is_wont(option)) ||
- my_want_state_is_wont(option))
- return;
- set_my_want_state_wont(option);
- will_wont_resp[option]++;
- }
- output_data ((const char *)wont, option);
-
- DIAG(TD_OPTIONS, printoption("td: send wont", option));
-}
-
-void
-dontoption(int option)
-{
- /*
- * Process client input.
- */
-
-
- DIAG(TD_OPTIONS, printoption("td: recv dont", option));
-
- if (will_wont_resp[option]) {
- will_wont_resp[option]--;
- if (will_wont_resp[option] && my_state_is_wont(option))
- will_wont_resp[option]--;
- }
- if ((will_wont_resp[option] == 0) && (my_want_state_is_will(option))) {
- switch (option) {
- case TELOPT_BINARY:
- init_termbuf();
- tty_binaryout(0);
- set_termbuf();
- break;
-
- case TELOPT_ECHO: /* we should stop echoing */
- {
- init_termbuf();
- tty_setecho(0);
- set_termbuf();
- }
- break;
-
- case TELOPT_SGA:
- set_my_want_state_wont(option);
- if (my_state_is_will(option))
- send_wont(option, 0);
- set_my_state_wont(option);
- if (turn_on_sga ^= 1)
- send_will(option, 1);
- return;
-
- default:
- break;
- }
-
- set_my_want_state_wont(option);
- if (my_state_is_will(option))
- send_wont(option, 0);
- }
- set_my_state_wont(option);
-
-} /* end of dontoption */
-
-#ifdef ENV_HACK
-int env_ovar = -1;
-int env_ovalue = -1;
-#else /* ENV_HACK */
-# define env_ovar OLD_ENV_VAR
-# define env_ovalue OLD_ENV_VALUE
-#endif /* ENV_HACK */
-
-/*
- * variables not to let through.
- * if name ends in =, it is complete variable name
- * if it does not end in =, all variables starting with this name
- * should be dropped.
- */
-char *badenv_table[] = {
- "IFS=",
- "LD_",
- "_RLD_",
- "SHLIB_PATH=",
- "LIBPATH=",
- "KRB",
- "ENV=",
- "BASH_ENV=",
- NULL,
-};
-
-static int envvarok(char *);
-
-/* envvarok(char*) */
-/* check that variable is safe to pass to login or shell */
-static int
-envvarok(varp)
- char *varp;
-{
- int i;
- int len;
-
- if (strchr(varp, '='))
- return (0);
- for (i = 0; badenv_table[i]; i++) {
- len = strlen(badenv_table[i]);
- if (badenv_table[i][len-1] == '=' &&
- !strncmp(badenv_table[i], varp, len-1) &&
- varp[len-2] == '\0')
- return (0);
- if (!strncmp(badenv_table[i], varp, len-1))
- return (0);
- }
- return (1);
-}
-
-/*
- * suboption()
- *
- * Look at the sub-option buffer, and try to be helpful to the other
- * side.
- *
- * Currently we recognize:
- *
- * Terminal type is
- * Linemode
- * Window size
- * Terminal speed
- */
-void
-suboption(void)
-{
- int subchar;
-
- DIAG(TD_OPTIONS, {netflush(); printsub('<', subpointer, SB_LEN()+2);});
-
- subchar = SB_GET();
- switch (subchar) {
- case TELOPT_TSPEED: {
- int xspeed, rspeed;
-
- if (his_state_is_wont(TELOPT_TSPEED)) /* Ignore if option disabled */
- break;
-
- settimer(tspeedsubopt);
-
- if (SB_EOF() || SB_GET() != TELQUAL_IS)
- return;
-
- xspeed = atoi((char *)subpointer);
-
- while (SB_GET() != ',' && !SB_EOF());
- if (SB_EOF())
- return;
-
- rspeed = atoi((char *)subpointer);
- clientstat(TELOPT_TSPEED, xspeed, rspeed);
-
- break;
-
- } /* end of case TELOPT_TSPEED */
-
- case TELOPT_TTYPE: { /* Yaaaay! */
- char *tt;
-
- if (his_state_is_wont(TELOPT_TTYPE)) /* Ignore if option disabled */
- break;
- settimer(ttypesubopt);
-
- if (SB_EOF() || SB_GET() != TELQUAL_IS) {
- return; /* ??? XXX but, this is the most robust */
- }
-
- tt = terminaltype;
-
- while ((tt < (terminaltype + sizeof terminaltype-1)) &&
- !SB_EOF()) {
- int c;
-
- c = SB_GET();
- if (isupper(c)) {
- c = tolower(c);
- }
- *tt++ = c; /* accumulate name */
- }
- *tt = 0;
- break;
- } /* end of case TELOPT_TTYPE */
-
- case TELOPT_NAWS: {
- int xwinsize, ywinsize;
-
- if (his_state_is_wont(TELOPT_NAWS)) /* Ignore if option disabled */
- break;
-
- if (SB_EOF())
- return;
- xwinsize = SB_GET() << 8;
- if (SB_EOF())
- return;
- xwinsize |= SB_GET();
- if (SB_EOF())
- return;
- ywinsize = SB_GET() << 8;
- if (SB_EOF())
- return;
- ywinsize |= SB_GET();
- clientstat(TELOPT_NAWS, xwinsize, ywinsize);
-
- break;
-
- } /* end of case TELOPT_NAWS */
-
- case TELOPT_STATUS: {
- int mode;
-
- if (SB_EOF())
- break;
- mode = SB_GET();
- switch (mode) {
- case TELQUAL_SEND:
- if (my_state_is_will(TELOPT_STATUS))
- send_status();
- break;
-
- case TELQUAL_IS:
- break;
-
- default:
- break;
- }
- break;
- } /* end of case TELOPT_STATUS */
-
- case TELOPT_XDISPLOC: {
- if (SB_EOF() || SB_GET() != TELQUAL_IS)
- return;
- settimer(xdisplocsubopt);
- subpointer[SB_LEN()] = '\0';
- esetenv("DISPLAY", (char *)subpointer, 1);
- break;
- } /* end of case TELOPT_XDISPLOC */
-
-#ifdef TELOPT_NEW_ENVIRON
- case TELOPT_NEW_ENVIRON:
-#endif
- case TELOPT_OLD_ENVIRON: {
- int c;
- char *cp, *varp, *valp;
-
- if (SB_EOF())
- return;
- c = SB_GET();
- if (c == TELQUAL_IS) {
- if (subchar == TELOPT_OLD_ENVIRON)
- settimer(oenvironsubopt);
- else
- settimer(environsubopt);
- } else if (c != TELQUAL_INFO) {
- return;
- }
-
-#ifdef TELOPT_NEW_ENVIRON
- if (subchar == TELOPT_NEW_ENVIRON) {
- while (!SB_EOF()) {
- c = SB_GET();
- if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR))
- break;
- }
- } else
-#endif
- {
-#ifdef ENV_HACK
- /*
- * We only want to do this if we haven't already decided
- * whether or not the other side has its VALUE and VAR
- * reversed.
- */
- if (env_ovar < 0) {
- int last = -1; /* invalid value */
- int empty = 0;
- int got_var = 0, got_value = 0, got_uservar = 0;
-
- /*
- * The other side might have its VALUE and VAR values
- * reversed. To be interoperable, we need to determine
- * which way it is. If the first recognized character
- * is a VAR or VALUE, then that will tell us what
- * type of client it is. If the fist recognized
- * character is a USERVAR, then we continue scanning
- * the suboption looking for two consecutive
- * VAR or VALUE fields. We should not get two
- * consecutive VALUE fields, so finding two
- * consecutive VALUE or VAR fields will tell us
- * what the client is.
- */
- SB_SAVE();
- while (!SB_EOF()) {
- c = SB_GET();
- switch(c) {
- case OLD_ENV_VAR:
- if (last < 0 || last == OLD_ENV_VAR
- || (empty && (last == OLD_ENV_VALUE)))
- goto env_ovar_ok;
- got_var++;
- last = OLD_ENV_VAR;
- break;
- case OLD_ENV_VALUE:
- if (last < 0 || last == OLD_ENV_VALUE
- || (empty && (last == OLD_ENV_VAR)))
- goto env_ovar_wrong;
- got_value++;
- last = OLD_ENV_VALUE;
- break;
- case ENV_USERVAR:
- /* count strings of USERVAR as one */
- if (last != ENV_USERVAR)
- got_uservar++;
- if (empty) {
- if (last == OLD_ENV_VALUE)
- goto env_ovar_ok;
- if (last == OLD_ENV_VAR)
- goto env_ovar_wrong;
- }
- last = ENV_USERVAR;
- break;
- case ENV_ESC:
- if (!SB_EOF())
- c = SB_GET();
- /* FALL THROUGH */
- default:
- empty = 0;
- continue;
- }
- empty = 1;
- }
- if (empty) {
- if (last == OLD_ENV_VALUE)
- goto env_ovar_ok;
- if (last == OLD_ENV_VAR)
- goto env_ovar_wrong;
- }
- /*
- * Ok, the first thing was a USERVAR, and there
- * are not two consecutive VAR or VALUE commands,
- * and none of the VAR or VALUE commands are empty.
- * If the client has sent us a well-formed option,
- * then the number of VALUEs received should always
- * be less than or equal to the number of VARs and
- * USERVARs received.
- *
- * If we got exactly as many VALUEs as VARs and
- * USERVARs, the client has the same definitions.
- *
- * If we got exactly as many VARs as VALUEs and
- * USERVARS, the client has reversed definitions.
- */
- if (got_uservar + got_var == got_value) {
- env_ovar_ok:
- env_ovar = OLD_ENV_VAR;
- env_ovalue = OLD_ENV_VALUE;
- } else if (got_uservar + got_value == got_var) {
- env_ovar_wrong:
- env_ovar = OLD_ENV_VALUE;
- env_ovalue = OLD_ENV_VAR;
- DIAG(TD_OPTIONS, {
- output_data("ENVIRON VALUE and VAR are reversed!\r\n");
- });
-
- }
- }
- SB_RESTORE();
-#endif
-
- while (!SB_EOF()) {
- c = SB_GET();
- if ((c == env_ovar) || (c == ENV_USERVAR))
- break;
- }
- }
-
- if (SB_EOF())
- return;
-
- cp = varp = (char *)subpointer;
- valp = 0;
-
- while (!SB_EOF()) {
- c = SB_GET();
- if (subchar == TELOPT_OLD_ENVIRON) {
- if (c == env_ovar)
- c = NEW_ENV_VAR;
- else if (c == env_ovalue)
- c = NEW_ENV_VALUE;
- }
- switch (c) {
-
- case NEW_ENV_VALUE:
- *cp = '\0';
- cp = valp = (char *)subpointer;
- break;
-
- case NEW_ENV_VAR:
- case ENV_USERVAR:
- *cp = '\0';
- if(envvarok(varp)) {
- if (valp)
- esetenv(varp, valp, 1);
- else
- unsetenv(varp);
- }
- cp = varp = (char *)subpointer;
- valp = 0;
- break;
-
- case ENV_ESC:
- if (SB_EOF())
- break;
- c = SB_GET();
- /* FALL THROUGH */
- default:
- *cp++ = c;
- break;
- }
- }
- *cp = '\0';
- if(envvarok(varp)) {
- if (valp)
- esetenv(varp, valp, 1);
- else
- unsetenv(varp);
- }
- break;
- } /* end of case TELOPT_NEW_ENVIRON */
-#ifdef AUTHENTICATION
- case TELOPT_AUTHENTICATION:
- if (SB_EOF())
- break;
- switch(SB_GET()) {
- case TELQUAL_SEND:
- case TELQUAL_REPLY:
- /*
- * These are sent by us and cannot be sent by
- * the client.
- */
- break;
- case TELQUAL_IS:
- auth_is(subpointer, SB_LEN());
- break;
- case TELQUAL_NAME:
- auth_name(subpointer, SB_LEN());
- break;
- }
- break;
-#endif
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- if (SB_EOF())
- break;
- switch(SB_GET()) {
- case ENCRYPT_SUPPORT:
- encrypt_support(subpointer, SB_LEN());
- break;
- case ENCRYPT_IS:
- encrypt_is(subpointer, SB_LEN());
- break;
- case ENCRYPT_REPLY:
- encrypt_reply(subpointer, SB_LEN());
- break;
- case ENCRYPT_START:
- encrypt_start(subpointer, SB_LEN());
- break;
- case ENCRYPT_END:
- encrypt_end();
- break;
- case ENCRYPT_REQSTART:
- encrypt_request_start(subpointer, SB_LEN());
- break;
- case ENCRYPT_REQEND:
- /*
- * We can always send an REQEND so that we cannot
- * get stuck encrypting. We should only get this
- * if we have been able to get in the correct mode
- * anyhow.
- */
- encrypt_request_end();
- break;
- case ENCRYPT_ENC_KEYID:
- encrypt_enc_keyid(subpointer, SB_LEN());
- break;
- case ENCRYPT_DEC_KEYID:
- encrypt_dec_keyid(subpointer, SB_LEN());
- break;
- default:
- break;
- }
- break;
-#endif
-
- default:
- break;
- } /* end of switch */
-
-} /* end of suboption */
-
-void
-doclientstat(void)
-{
- clientstat(TELOPT_LINEMODE, WILL, 0);
-}
-
-#define ADD(c) *ncp++ = c
-#define ADD_DATA(c) { *ncp++ = c; if (c == SE || c == IAC) *ncp++ = c; }
-
-void
-send_status(void)
-{
- unsigned char statusbuf[256];
- unsigned char *ncp;
- unsigned char i;
-
- ncp = statusbuf;
-
- netflush(); /* get rid of anything waiting to go out */
-
- ADD(IAC);
- ADD(SB);
- ADD(TELOPT_STATUS);
- ADD(TELQUAL_IS);
-
- /*
- * We check the want_state rather than the current state,
- * because if we received a DO/WILL for an option that we
- * don't support, and the other side didn't send a DONT/WONT
- * in response to our WONT/DONT, then the "state" will be
- * WILL/DO, and the "want_state" will be WONT/DONT. We
- * need to go by the latter.
- */
- for (i = 0; i < (unsigned char)NTELOPTS; i++) {
- if (my_want_state_is_will(i)) {
- ADD(WILL);
- ADD_DATA(i);
- }
- if (his_want_state_is_will(i)) {
- ADD(DO);
- ADD_DATA(i);
- }
- }
-
- if (his_want_state_is_will(TELOPT_LFLOW)) {
- ADD(SB);
- ADD(TELOPT_LFLOW);
- if (flowmode) {
- ADD(LFLOW_ON);
- } else {
- ADD(LFLOW_OFF);
- }
- ADD(SE);
-
- if (restartany >= 0) {
- ADD(SB);
- ADD(TELOPT_LFLOW);
- if (restartany) {
- ADD(LFLOW_RESTART_ANY);
- } else {
- ADD(LFLOW_RESTART_XON);
- }
- ADD(SE);
- }
- }
-
-
- ADD(IAC);
- ADD(SE);
-
- writenet(statusbuf, ncp - statusbuf);
- netflush(); /* Send it on its way */
-
- DIAG(TD_OPTIONS,
- {printsub('>', statusbuf, ncp - statusbuf); netflush();});
-}
diff --git a/libexec/telnetd/sys_term.c b/libexec/telnetd/sys_term.c
deleted file mode 100644
index bf5030fd87d..00000000000
--- a/libexec/telnetd/sys_term.c
+++ /dev/null
@@ -1,1911 +0,0 @@
-/*
- * 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 "telnetd.h"
-
-/* RCSID("$KTH: sys_term.c,v 1.100 2001/04/24 23:11:43 assar Exp $"); */
-
-#if defined(_CRAY) || (defined(__hpux) && !defined(HAVE_UTMPX_H))
-# define PARENT_DOES_UTMP
-#endif
-
-#ifdef HAVE_UTMP_H
-#include <utmp.h>
-#endif
-
-#ifdef HAVE_UTMPX_H
-#include <utmpx.h>
-#endif
-
-#ifdef HAVE_UTMPX_H
-struct utmpx wtmp;
-#elif defined(HAVE_UTMP_H)
-struct utmp wtmp;
-#endif /* HAVE_UTMPX_H */
-
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
-int utmp_len = sizeof(wtmp.ut_host);
-#else
-int utmp_len = MAXHOSTNAMELEN;
-#endif
-
-#ifndef UTMP_FILE
-#ifdef _PATH_UTMP
-#define UTMP_FILE _PATH_UTMP
-#else
-#define UTMP_FILE "/etc/utmp"
-#endif
-#endif
-
-#if !defined(WTMP_FILE) && defined(_PATH_WTMP)
-#define WTMP_FILE _PATH_WTMP
-#endif
-
-#ifndef PARENT_DOES_UTMP
-#ifdef WTMP_FILE
-char wtmpf[] = WTMP_FILE;
-#else
-char wtmpf[] = "/usr/adm/wtmp";
-#endif
-char utmpf[] = UTMP_FILE;
-#else /* PARENT_DOES_UTMP */
-#ifdef WTMP_FILE
-char wtmpf[] = WTMP_FILE;
-#else
-char wtmpf[] = "/etc/wtmp";
-#endif
-#endif /* PARENT_DOES_UTMP */
-
-#ifdef HAVE_TMPDIR_H
-#include <tmpdir.h>
-#endif /* CRAY */
-
-#ifdef STREAMSPTY
-
-#ifdef HAVE_SAC_H
-#include <sac.h>
-#endif
-
-#ifdef HAVE_SYS_STROPTS_H
-#include <sys/stropts.h>
-#endif
-
-#endif /* STREAMSPTY */
-
-#ifdef HAVE_SYS_STREAM_H
-#ifdef HAVE_SYS_UIO_H
-#include <sys/uio.h>
-#endif
-#ifdef __hpux
-#undef SE
-#endif
-#include <sys/stream.h>
-#endif
-#if !(defined(__sgi) || defined(__linux) || defined(_AIX)) && defined(HAVE_SYS_TTY)
-#include <sys/tty.h>
-#endif
-#ifdef t_erase
-#undef t_erase
-#undef t_kill
-#undef t_intrc
-#undef t_quitc
-#undef t_startc
-#undef t_stopc
-#undef t_eofc
-#undef t_brkc
-#undef t_suspc
-#undef t_dsuspc
-#undef t_rprntc
-#undef t_flushc
-#undef t_werasc
-#undef t_lnextc
-#endif
-
-#ifdef HAVE_TERMIOS_H
-#include <termios.h>
-#else
-#ifdef HAVE_TERMIO_H
-#include <termio.h>
-#endif
-#endif
-
-#ifdef HAVE_UTIL_H
-#include <util.h>
-#endif
-
-# ifndef TCSANOW
-# ifdef TCSETS
-# define TCSANOW TCSETS
-# define TCSADRAIN TCSETSW
-# define tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)
-# else
-# ifdef TCSETA
-# define TCSANOW TCSETA
-# define TCSADRAIN TCSETAW
-# define tcgetattr(f, t) ioctl(f, TCGETA, (char *)t)
-# else
-# define TCSANOW TIOCSETA
-# define TCSADRAIN TIOCSETAW
-# define tcgetattr(f, t) ioctl(f, TIOCGETA, (char *)t)
-# endif
-# endif
-# define tcsetattr(f, a, t) ioctl(f, a, t)
-# define cfsetospeed(tp, val) (tp)->c_cflag &= ~CBAUD; \
-(tp)->c_cflag |= (val)
-# define cfgetospeed(tp) ((tp)->c_cflag & CBAUD)
-# ifdef CIBAUD
-# define cfsetispeed(tp, val) (tp)->c_cflag &= ~CIBAUD; \
- (tp)->c_cflag |= ((val)<<IBSHIFT)
-# define cfgetispeed(tp) (((tp)->c_cflag & CIBAUD)>>IBSHIFT)
-# else
-# define cfsetispeed(tp, val) (tp)->c_cflag &= ~CBAUD; \
- (tp)->c_cflag |= (val)
-# define cfgetispeed(tp) ((tp)->c_cflag & CBAUD)
-# endif
-# endif /* TCSANOW */
- struct termios termbuf, termbuf2; /* pty control structure */
-# ifdef STREAMSPTY
- static int ttyfd = -1;
- int really_stream = 0;
-# endif
-
- char *new_login = NULL;
-
-/*
- * 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)
-{
-# ifdef STREAMSPTY
- if (really_stream)
- tcgetattr(ttyfd, &termbuf);
- else
-# endif
- tcgetattr(ourpty, &termbuf);
- termbuf2 = termbuf;
-}
-
-void
-set_termbuf(void)
-{
- /*
- * Only make the necessary changes.
- */
- if (memcmp(&termbuf, &termbuf2, sizeof(termbuf)))
-# ifdef STREAMSPTY
- if (really_stream)
- tcsetattr(ttyfd, TCSANOW, &termbuf);
- else
-# endif
- tcsetattr(ourpty, 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:
-#ifdef VSTART
- setval(VSTART, SLC_VARIABLE);
-#else
- defval(0x13);
-#endif
- case SLC_XOFF:
-#ifdef VSTOP
- setval(VSTOP, SLC_VARIABLE);
-#else
- defval(0x11);
-#endif
- case SLC_EW:
-#ifdef VWERASE
- setval(VWERASE, SLC_VARIABLE);
-#else
- defval(0);
-#endif
- case SLC_RP:
-#ifdef VREPRINT
- setval(VREPRINT, SLC_VARIABLE);
-#else
- defval(0);
-#endif
- case SLC_LNEXT:
-#ifdef VLNEXT
- setval(VLNEXT, SLC_VARIABLE);
-#else
- defval(0);
-#endif
- case SLC_AO:
-#if !defined(VDISCARD) && defined(VFLUSHO)
-# define VDISCARD VFLUSHO
-#endif
-#ifdef VDISCARD
- setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);
-#else
- defval(0);
-#endif
- case SLC_SUSP:
-#ifdef VSUSP
- setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN);
-#else
- defval(0);
-#endif
-#ifdef VEOL
- case SLC_FORW1:
- setval(VEOL, SLC_VARIABLE);
-#endif
-#ifdef VEOL2
- case SLC_FORW2:
- setval(VEOL2, SLC_VARIABLE);
-#endif
- case SLC_AYT:
-#ifdef VSTATUS
- setval(VSTATUS, SLC_VARIABLE);
-#else
- defval(0);
-#endif
-
- case SLC_BRK:
- case SLC_SYNCH:
- case SLC_EOR:
- defval(0);
-
- default:
- *valp = 0;
- *valpp = 0;
- return(SLC_NOSUPPORT);
- }
-}
-
-#ifdef _CRAY
-/*
- * getnpty()
- *
- * Return the number of pty's configured into the system.
- */
-int
-getnpty()
-{
-#ifdef _SC_CRAY_NPTY
- int numptys;
-
- if ((numptys = sysconf(_SC_CRAY_NPTY)) != -1)
- return numptys;
- else
-#endif /* _SC_CRAY_NPTY */
- return 128;
-}
-#endif /* CRAY */
-
-/*
- * 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.
- */
-
-static char Xline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-char *line = Xline;
-
-int slavefd = -1;
-
-#ifdef _CRAY
-char myline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-#endif /* CRAY */
-
-#if !defined(HAVE_PTSNAME) && defined(STREAMSPTY)
-static char *ptsname(int fd)
-{
-#ifdef HAVE_TTYNAME
- return ttyname(fd);
-#else
- return NULL;
-#endif
-}
-#endif
-
-int getpty(int *ptynum)
-{
-#if defined(__osf__) || defined(HAVE_OPENPTY)
- int master;
- int slave;
- if(openpty(&master, &slave, line, 0, 0) == 0){
- slavefd = slave;
- return master;
- }
- return -1;
-#else
-#ifdef HAVE__GETPTY
- int master, slave;
- char *p;
- p = _getpty(&master, O_RDWR, 0600, 1);
- if(p == NULL)
- return -1;
- strlcpy(line, p, sizeof(Xline));
- return master;
-#else
-
- int p;
- char *cp, *p1, *p2;
- int i;
-#if SunOS == 40
- int dummy;
-#endif
-#if 0 /* && defined(HAVE_OPENPTY) */
- int master;
- int slave;
- if(openpty(&master, &slave, line, 0, 0) == 0){
- close(slave);
- return master;
- }
-#else
-#ifdef STREAMSPTY
- char *clone[] = { "/dev/ptc", "/dev/ptmx", "/dev/ptm",
- "/dev/ptym/clone", 0 };
-
- char **q;
- for(q=clone; *q; q++){
- p=open(*q, O_RDWR);
- if(p >= 0){
-#ifdef HAVE_GRANTPT
- grantpt(p);
-#endif
-#ifdef HAVE_UNLOCKPT
- unlockpt(p);
-#endif
- strlcpy(line, ptsname(p), sizeof(Xline));
- really_stream = 1;
- return p;
- }
- }
-#endif /* STREAMSPTY */
-#ifndef _CRAY
-
-#ifndef __hpux
- snprintf(line, sizeof(Xline), "/dev/ptyXX");
- p1 = &line[8];
- p2 = &line[9];
-#else
- snprintf(line, sizeof(Xline), "/dev/ptym/ptyXX");
- p1 = &line[13];
- p2 = &line[14];
-#endif
-
-
- for (cp = "pqrstuvwxyzPQRST"; *cp; cp++) {
- struct stat stb;
-
- *p1 = *cp;
- *p2 = '0';
- /*
- * This stat() check is just to keep us from
- * looping through all 256 combinations if there
- * aren't that many ptys available.
- */
- if (stat(line, &stb) < 0)
- break;
- for (i = 0; i < 16; i++) {
- *p2 = "0123456789abcdef"[i];
- p = open(line, O_RDWR);
- if (p > 0) {
-#ifndef __hpux
- line[5] = 't';
-#else
- for (p1 = &line[8]; *p1; p1++)
- *p1 = *(p1+1);
- line[9] = 't';
-#endif
- chown(line, 0, 0);
- chmod(line, 0600);
-#if SunOS == 40
- if (ioctl(p, TIOCGPGRP, &dummy) == 0
- || errno != EIO) {
- chmod(line, 0666);
- close(p);
- line[5] = 'p';
- } else
-#endif /* SunOS == 40 */
- return(p);
- }
- }
- }
-#else /* CRAY */
- extern lowpty, highpty;
- struct stat sb;
-
- for (*ptynum = lowpty; *ptynum <= highpty; (*ptynum)++) {
- snprintf(myline, sizeof(myline), "/dev/pty/%03d", *ptynum);
- p = open(myline, 2);
- if (p < 0)
- continue;
- snprintf(line, sizeof(Xline), "/dev/ttyp%03d", *ptynum);
- /*
- * Here are some shenanigans to make sure that there
- * are no listeners lurking on the line.
- */
- if(stat(line, &sb) < 0) {
- close(p);
- continue;
- }
- if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
- chown(line, 0, 0);
- chmod(line, 0600);
- close(p);
- p = open(myline, 2);
- if (p < 0)
- continue;
- }
- /*
- * Now it should be safe...check for accessability.
- */
- if (access(line, 6) == 0)
- return(p);
- else {
- /* no tty side to pty so skip it */
- close(p);
- }
- }
-#endif /* CRAY */
-#endif /* STREAMSPTY */
-#endif /* OPENPTY */
- return(-1);
-#endif
-}
-
-
-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));
-}
-
-
-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);
-}
-
-/*
- * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD).
- */
-#if B4800 != 4800
-#define DECODE_BAUD
-#endif
-
-#ifdef DECODE_BAUD
-
-/*
- * A table of available terminal speeds
- */
-struct termspeeds {
- int speed;
- int value;
-} termspeeds[] = {
- { 0, B0 }, { 50, B50 }, { 75, B75 },
- { 110, B110 }, { 134, B134 }, { 150, B150 },
- { 200, B200 }, { 300, B300 }, { 600, B600 },
- { 1200, B1200 }, { 1800, B1800 }, { 2400, B2400 },
- { 4800, B4800 },
-#ifdef B7200
- { 7200, B7200 },
-#endif
- { 9600, B9600 },
-#ifdef B14400
- { 14400, B14400 },
-#endif
-#ifdef B19200
- { 19200, B19200 },
-#endif
-#ifdef B28800
- { 28800, B28800 },
-#endif
-#ifdef B38400
- { 38400, B38400 },
-#endif
-#ifdef B57600
- { 57600, B57600 },
-#endif
-#ifdef B115200
- { 115200, B115200 },
-#endif
-#ifdef B230400
- { 230400, B230400 },
-#endif
- { -1, 0 }
-};
-#endif /* DECODE_BUAD */
-
-void
-tty_tspeed(int val)
-{
-#ifdef DECODE_BAUD
- struct termspeeds *tp;
-
- for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
- ;
- if (tp->speed == -1) /* back up to last valid value */
- --tp;
- cfsetospeed(&termbuf, tp->value);
-#else /* DECODE_BUAD */
- cfsetospeed(&termbuf, val);
-#endif /* DECODE_BUAD */
-}
-
-void
-tty_rspeed(int val)
-{
-#ifdef DECODE_BAUD
- struct termspeeds *tp;
-
- for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
- ;
- if (tp->speed == -1) /* back up to last valid value */
- --tp;
- cfsetispeed(&termbuf, tp->value);
-#else /* DECODE_BAUD */
- cfsetispeed(&termbuf, val);
-#endif /* DECODE_BAUD */
-}
-
-#ifdef PARENT_DOES_UTMP
-extern struct utmp wtmp;
-extern char wtmpf[];
-
-extern void utmp_sig_init (void);
-extern void utmp_sig_reset (void);
-extern void utmp_sig_wait (void);
-extern void utmp_sig_notify (int);
-# endif /* PARENT_DOES_UTMP */
-
-#ifdef STREAMSPTY
-
-/* I_FIND seems to live a life of its own */
-static int my_find(int fd, char *module)
-{
-#if defined(I_FIND) && defined(I_LIST)
- static int flag;
- static struct str_list sl;
- int n;
- int i;
-
- if(!flag){
- n = ioctl(fd, I_LIST, 0);
- if(n < 0){
- perror("ioctl(fd, I_LIST, 0)");
- return -1;
- }
- sl.sl_modlist=(struct str_mlist*)malloc(n * sizeof(struct str_mlist));
- sl.sl_nmods = n;
- n = ioctl(fd, I_LIST, &sl);
- if(n < 0){
- perror("ioctl(fd, I_LIST, n)");
- return -1;
- }
- flag = 1;
- }
-
- for(i=0; i<sl.sl_nmods; i++)
- if(!strcmp(sl.sl_modlist[i].l_name, module))
- return 1;
-#endif
- return 0;
-}
-
-static void maybe_push_modules(int fd, char **modules)
-{
- char **p;
- int err;
-
- for(p=modules; *p; p++){
- err = my_find(fd, *p);
- if(err == 1)
- break;
- if(err < 0 && errno != EINVAL)
- fatalperror(net, "my_find()");
- /* module not pushed or does not exist */
- }
- /* p points to null or to an already pushed module, now push all
- modules before this one */
-
- for(p--; p >= modules; p--){
- err = ioctl(fd, I_PUSH, *p);
- if(err < 0 && errno != EINVAL)
- fatalperror(net, "I_PUSH");
- }
-}
-#endif
-
-/*
- * 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.
- */
-void getptyslave(void)
-{
- int t = -1;
-
- struct winsize ws;
- extern int def_row, def_col;
- extern int def_tspeed, def_rspeed;
- /*
- * 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.
- */
-
- if (slavefd != -1) {
- t = slavefd;
- goto gottty;
- }
-
- /*
- * Make sure that we don't have a controlling tty, and
- * that we are the session (process group) leader.
- */
-
-#ifdef HAVE_SETSID
- if(setsid()<0)
- fatalperror(net, "setsid()");
-#else
-# ifdef TIOCNOTTY
- t = open(_PATH_TTY, O_RDWR);
- if (t >= 0) {
- ioctl(t, TIOCNOTTY, (char *)0);
- close(t);
- }
-# endif
-#endif
-
-# ifdef PARENT_DOES_UTMP
- /*
- * Wait for our parent to get the utmp stuff to get done.
- */
- utmp_sig_wait();
-# endif
-
- t = cleanopen(line);
-gottty:
- if (t < 0)
- fatalperror(net, line);
-
-#ifdef STREAMSPTY
- ttyfd = t;
-
-
- /*
- * Not all systems have (or need) modules ttcompat and pckt so
- * don't flag it as a fatal error if they don't exist.
- */
-
- if (really_stream)
- {
- /* these are the streams modules that we want pushed. note
- that they are in reverse order, ptem will be pushed
- first. maybe_push_modules() will try to push all modules
- before the first one that isn't already pushed. i.e if
- ldterm is pushed, only ttcompat will be attempted.
-
- all this is because we don't know which modules are
- available, and we don't know which modules are already
- pushed (via autopush, for instance).
-
- */
-
- char *ttymodules[] = { "ttcompat", "ldterm", "ptem", NULL };
- char *ptymodules[] = { "pckt", NULL };
-
- maybe_push_modules(t, ttymodules);
- maybe_push_modules(ourpty, ptymodules);
- }
-#endif
- /*
- * set up the tty modes as we like them to be.
- */
- init_termbuf();
-# ifdef TIOCSWINSZ
- if (def_row || def_col) {
- memset(&ws, 0, sizeof(ws));
- ws.ws_col = def_col;
- ws.ws_row = def_row;
- ioctl(t, TIOCSWINSZ, (char *)&ws);
- }
-# endif
-
- /*
- * Settings for sgtty based systems
- */
-
- /*
- * Settings for UNICOS (and HPUX)
- */
-# if defined(_CRAY) || defined(__hpux)
- termbuf.c_oflag = OPOST|ONLCR|TAB3;
- termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;
- termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
- termbuf.c_cflag = EXTB|HUPCL|CS8;
-# endif
-
- /*
- * Settings for all other termios/termio based
- * systems, other than 4.4BSD. In 4.4BSD the
- * kernel does the initial terminal setup.
- */
-# if !(defined(_CRAY) || defined(__hpux)) && (BSD <= 43)
-# ifndef OXTABS
-# define OXTABS 0
-# endif
- termbuf.c_lflag |= ECHO;
- termbuf.c_oflag |= ONLCR|OXTABS;
- termbuf.c_iflag |= ICRNL;
- termbuf.c_iflag &= ~IXOFF;
-# endif
- tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600);
- tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600);
-
- /*
- * Set the tty modes, and make this our controlling tty.
- */
- set_termbuf();
- if (login_tty(t) == -1)
- fatalperror(net, "login_tty");
- if (net > 2)
- close(net);
- if (ourpty > 2) {
- close(ourpty);
- ourpty = -1;
- }
-}
-
-#ifndef O_NOCTTY
-#define O_NOCTTY 0
-#endif
-/*
- * Open the specified slave side of the pty,
- * making sure that we have a clean tty.
- */
-
-int cleanopen(char *line)
-{
- int t;
-
-#ifdef STREAMSPTY
- if (!really_stream)
-#endif
- {
- /*
- * Make sure that other people can't open the
- * slave side of the connection.
- */
- chown(line, 0, 0);
- chmod(line, 0600);
- }
-
-#ifdef HAVE_REVOKE
- revoke(line);
-#endif
-
- t = open(line, O_RDWR|O_NOCTTY);
-
- if (t < 0)
- return(-1);
-
- /*
- * Hangup anybody else using this ttyp, then reopen it for
- * ourselves.
- */
-# if !(defined(_CRAY) || defined(__hpux)) && (BSD <= 43) && !defined(STREAMSPTY)
- signal(SIGHUP, SIG_IGN);
-#ifdef HAVE_VHANGUP
- vhangup();
-#else
-#endif
- signal(SIGHUP, SIG_DFL);
- t = open(line, O_RDWR|O_NOCTTY);
- if (t < 0)
- return(-1);
-# endif
-# if defined(_CRAY) && defined(TCVHUP)
- {
- int i;
- signal(SIGHUP, SIG_IGN);
- ioctl(t, TCVHUP, (char *)0);
- signal(SIGHUP, SIG_DFL);
-
- i = open(line, O_RDWR);
-
- if (i < 0)
- return(-1);
- close(t);
- t = i;
- }
-# endif /* defined(CRAY) && defined(TCVHUP) */
- return(t);
-}
-
-#if !defined(BSD4_4)
-
-int login_tty(int t)
-{
-# if defined(TIOCSCTTY) && !defined(__hpux)
- if (ioctl(t, TIOCSCTTY, (char *)0) < 0)
- fatalperror(net, "ioctl(sctty)");
-# ifdef _CRAY
- /*
- * Close the hard fd to /dev/ttypXXX, and re-open through
- * the indirect /dev/tty interface.
- */
- close(t);
- if ((t = open("/dev/tty", O_RDWR)) < 0)
- fatalperror(net, "open(/dev/tty)");
-# endif
-# else
- /*
- * We get our controlling tty assigned as a side-effect
- * of opening up a tty device. But on BSD based systems,
- * this only happens if our process group is zero. The
- * setsid() call above may have set our pgrp, so clear
- * it out before opening the tty...
- */
-#ifdef HAVE_SETPGID
- setpgid(0, 0);
-#else
- setpgrp(0, 0); /* if setpgid isn't available, setpgrp
- probably takes arguments */
-#endif
- close(open(line, O_RDWR));
-# endif
- if (t != 0)
- dup2(t, 0);
- if (t != 1)
- dup2(t, 1);
- if (t != 2)
- dup2(t, 2);
- if (t > 2)
- close(t);
- return(0);
-}
-#endif /* BSD <= 43 */
-
-/*
- * This comes from ../../bsd/tty.c and should not really be here.
- */
-
-/*
- * Clean the tty name. Return a pointer to the cleaned version.
- */
-
-static char *
-clean_ttyname (char *tty)
-{
- char *res = tty;
-
- if (strncmp (res, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
- res += sizeof(_PATH_DEV) - 1;
- if (strncmp (res, "pty/", 4) == 0)
- res += 4;
- if (strncmp (res, "ptym/", 5) == 0)
- res += 5;
- return res;
-}
-
-/*
- * Generate a name usable as an `ut_id', typically without `tty'.
- */
-
-#ifdef HAVE_STRUCT_UTMP_UT_ID
-static char *
-make_id (char *tty)
-{
- char *res = tty;
-
- if (strncmp (res, "pts/", 4) == 0)
- res += 4;
- if (strncmp (res, "tty", 3) == 0)
- res += 3;
- return res;
-}
-#endif
-
-/*
- * startslave(host)
- *
- * Given a hostname, do whatever
- * is necessary to startup the login process on the slave side of the pty.
- */
-
-/* ARGSUSED */
-void
-startslave(const char *host, const char *utmp_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
-
-# ifdef PARENT_DOES_UTMP
- utmp_sig_init();
-# endif /* PARENT_DOES_UTMP */
-
- if ((i = fork()) < 0)
- fatalperror(net, "fork");
- if (i) {
-# ifdef PARENT_DOES_UTMP
- /*
- * Cray parent will create utmp entry for child and send
- * signal to child to tell when done. Child waits for signal
- * before doing anything important.
- */
- int pid = i;
- void sigjob (int);
-
- setpgrp();
- utmp_sig_reset(); /* reset handler to default */
- /*
- * Create utmp entry for child
- */
- wtmp.ut_time = time(NULL);
- wtmp.ut_type = LOGIN_PROCESS;
- wtmp.ut_pid = pid;
- strncpy(wtmp.ut_user, "LOGIN", sizeof(wtmp.ut_user));
- strncpy(wtmp.ut_host, utmp_host, sizeof(wtmp.ut_host));
- strncpy(wtmp.ut_line, clean_ttyname(line), sizeof(wtmp.ut_line));
-#ifdef HAVE_STRUCT_UTMP_UT_ID
- strncpy(wtmp.ut_id, wtmp.ut_line + 3, sizeof(wtmp.ut_id));
-#endif
-
- pututline(&wtmp);
- endutent();
- if ((i = open(wtmpf, O_WRONLY|O_APPEND)) >= 0) {
- write(i, &wtmp, sizeof(struct utmp));
- close(i);
- }
-#ifdef _CRAY
- signal(WJSIGNAL, sigjob);
-#endif
- utmp_sig_notify(pid);
-# endif /* PARENT_DOES_UTMP */
- } else {
- getptyslave();
-#if defined(DCE)
- /* if we authenticated via K5, try and join the PAG */
- kerberos5_dfspag();
-#endif
- start_login(host, autologin, autoname);
- /*NOTREACHED*/
- }
-}
-
-char *envinit[3];
-extern char **environ;
-
-void
-init_env(void)
-{
- char **envp;
-
- envp = envinit;
- if ((*envp = getenv("TZ")))
- *envp++ -= 3;
-#if defined(_CRAY) || defined(__hpux)
- else
- *envp++ = "TZ=GMT0";
-#endif
- *envp = 0;
- environ = envinit;
-}
-
-/* We won't agree with the Heimdal people about the right way to check for
- * bad environment variables, so we don't use this code.
- * See envvarok() in state.c instead.
- */
-#if 0
-/*
- * scrub_env()
- *
- * We only accept the environment variables listed below.
- */
-
-static void
-scrub_env(void)
-{
- static const char *reject[] = {
- "TERMCAP=/",
- NULL
- };
-
- static const char *accept[] = {
- "XAUTH=", "XAUTHORITY=", "DISPLAY=",
- "TERM=",
- "EDITOR=",
- "PAGER=",
- "PRINTER=",
- "LOGNAME=",
- "POSIXLY_CORRECT=",
- "TERMCAP=",
- 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 = accept; *p; p++)
- if(strncmp(*cpp, *p, strlen(*p)) == 0)
- break;
- if(*p != NULL)
- *cpp2++ = *cpp;
- }
- *cpp2 = NULL;
-}
-#endif
-
-struct arg_val {
- int size;
- int argc;
- const char **argv;
-};
-
-static void addarg(struct arg_val*, const char*);
-
-/*
- * start_login(host)
- *
- * Assuming that we are now running as a child processes, this
- * function will turn us into the login process.
- */
-
-void
-start_login(const char *host, int autologin, char *name)
-{
- struct arg_val argv;
- char *user;
- int save_errno;
- char *buf;
- extern char *gettytab[2], *gettyent;
-
-#ifdef HAVE_UTMPX_H
- int pid = getpid();
- struct utmpx utmpx;
- char *clean_tty;
-
- /*
- * Create utmp entry for child
- */
-
- clean_tty = clean_ttyname(line);
- memset(&utmpx, 0, sizeof(utmpx));
- strncpy(utmpx.ut_user, ".telnet", sizeof(utmpx.ut_user));
- strncpy(utmpx.ut_line, clean_tty, sizeof(utmpx.ut_line));
-#ifdef HAVE_STRUCT_UTMP_UT_ID
- strncpy(utmpx.ut_id, make_id(clean_tty), sizeof(utmpx.ut_id));
-#endif
- utmpx.ut_pid = pid;
-
- utmpx.ut_type = LOGIN_PROCESS;
-
- gettimeofday (&utmpx.ut_tv, NULL);
- if (pututxline(&utmpx) == NULL)
- fatal(net, "pututxline failed");
-#endif
-
-#if 0
- scrub_env();
-#endif
- /*
- * -h : pass on name of host.
- * WARNING: -h is 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
- */
-
- /* init argv structure */
- argv.size=0;
- argv.argc=0;
- argv.argv=malloc(0); /*so we can call realloc later */
- addarg(&argv, "login");
- addarg(&argv, "-h");
- addarg(&argv, host);
- addarg(&argv, "-p");
- if(name[0])
- user = name;
- else
- user = getenv("USER");
-#ifdef AUTHENTICATION
- if (auth_level < 0 || autologin != AUTH_VALID) {
- if(!no_warn) {
- printf("User not authenticated. "
- "Using plaintext username and password\r\n");
- }
- if(log_unauth)
- syslog(LOG_INFO, "unauthenticated access from %s (%s)",
- host, user ? user : "unknown user");
- }
- if (auth_level >= 0 && autologin == AUTH_VALID)
- addarg(&argv, "-f");
-#endif
- if(user){
- addarg(&argv, "--");
- addarg(&argv, strdup(user));
- }
- if (new_login == NULL && cgetent(&buf, gettytab, gettyent) >= 0) {
- cgetstr(buf, "lo", &new_login);
- cgetclose();
- }
- if (new_login == NULL)
- new_login = _PATH_LOGIN;
-
- if (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");
- }
- 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(new_login, (char *const*)argv.argv);
- save_errno = errno;
- syslog(LOG_ERR, "%s: %m", new_login);
- fatalperror_errno(net, new_login, save_errno);
- /*NOTREACHED*/
-}
-
-static void
-addarg(struct arg_val *argv, const char *val)
-{
- const char **tmp;
-
- if (argv->size <= argv->argc+1) {
- tmp = realloc(argv->argv, sizeof(char*) * (argv->size + 10));
- if (tmp == NULL) {
- if (argv->argv)
- free(argv->argv);
- argv->argv = NULL;
- argv->size = 0;
- fatal (net, "realloc: out of memory");
- }
- argv->argv = tmp;
- argv->size+=10;
- }
- argv->argv[argv->argc++] = val;
- argv->argv[argv->argc] = NULL;
-}
-
-
-/*
- * rmut()
- *
- * This is the function called by cleanup() to
- * remove the utmp entry for this person.
- */
-
-#ifdef HAVE_UTMPX_H
-static void
-rmut(void)
-{
- struct utmpx utmpx, *non_save_utxp;
- char *clean_tty = clean_ttyname(line);
-
- /*
- * This updates the utmpx and utmp entries and make a wtmp/x entry
- */
-
- setutxent();
- memset(&utmpx, 0, sizeof(utmpx));
- strncpy(utmpx.ut_line, clean_tty, sizeof(utmpx.ut_line));
- utmpx.ut_type = LOGIN_PROCESS;
- non_save_utxp = getutxline(&utmpx);
- if (non_save_utxp) {
- struct utmpx *utxp;
- char user0;
-
- utxp = malloc(sizeof(struct utmpx));
- *utxp = *non_save_utxp;
- user0 = utxp->ut_user[0];
- utxp->ut_user[0] = '\0';
- utxp->ut_type = DEAD_PROCESS;
-#ifdef HAVE_STRUCT_UTMPX_UT_EXIT
-#ifdef _STRUCT___EXIT_STATUS
- utxp->ut_exit.__e_termination = 0;
- utxp->ut_exit.__e_exit = 0;
-#elif defined(__osf__) /* XXX */
- utxp->ut_exit.ut_termination = 0;
- utxp->ut_exit.ut_exit = 0;
-#else
- utxp->ut_exit.e_termination = 0;
- utxp->ut_exit.e_exit = 0;
-#endif
-#endif
- gettimeofday(&utxp->ut_tv, NULL);
- pututxline(utxp);
-#ifdef WTMPX_FILE
- utxp->ut_user[0] = user0;
- updwtmpx(WTMPX_FILE, utxp);
-#elif defined(WTMP_FILE)
- /* This is a strange system with a utmpx and a wtmp! */
- {
- int f = open(wtmpf, O_WRONLY|O_APPEND);
- struct utmp wtmp;
- if (f >= 0) {
- strncpy(wtmp.ut_line, clean_tty, sizeof(wtmp.ut_line));
- strncpy(wtmp.ut_name, "", sizeof(wtmp.ut_name));
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
- strncpy(wtmp.ut_host, "", sizeof(wtmp.ut_host));
-#endif
- wtmp.ut_time = time(NULL);
- write(f, &wtmp, sizeof(wtmp));
- close(f);
- }
- }
-#endif
- free (utxp);
- }
- endutxent();
-} /* end of rmut */
-#endif
-
-#if !defined(HAVE_UTMPX_H) && !(defined(_CRAY) || defined(__hpux))
-static void
-rmut(void)
-{
- int f;
- int found = 0;
- struct utmp *u, *utmp;
- int nutmp;
- struct stat statbf;
- char *clean_tty = clean_ttyname(line);
-
- f = open(utmpf, O_RDWR);
- if (f >= 0) {
- fstat(f, &statbf);
- utmp = (struct utmp *)malloc((unsigned)statbf.st_size);
- if (!utmp)
- syslog(LOG_ERR, "utmp malloc failed");
- if (statbf.st_size && utmp) {
- nutmp = read(f, utmp, (int)statbf.st_size);
- nutmp /= sizeof(struct utmp);
-
- for (u = utmp ; u < &utmp[nutmp] ; u++) {
- if (strncmp(u->ut_line,
- clean_tty,
- sizeof(u->ut_line)) ||
- u->ut_name[0]==0)
- continue;
- lseek(f, ((long)u)-((long)utmp), L_SET);
- strncpy(u->ut_name, "", sizeof(u->ut_name));
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
- strncpy(u->ut_host, "", sizeof(u->ut_host));
-#endif
- u->ut_time = time(NULL);
- write(f, u, sizeof(wtmp));
- found++;
- }
- }
- close(f);
- }
- if (found) {
- f = open(wtmpf, O_WRONLY|O_APPEND);
- if (f >= 0) {
- strncpy(wtmp.ut_line, clean_tty, sizeof(wtmp.ut_line));
- strncpy(wtmp.ut_name, "", sizeof(wtmp.ut_name));
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
- strncpy(wtmp.ut_host, "", sizeof(wtmp.ut_host));
-#endif
- wtmp.ut_time = time(NULL);
- write(f, &wtmp, sizeof(wtmp));
- close(f);
- }
- }
- chmod(line, 0666);
- chown(line, 0, 0);
- line[strlen("/dev/")] = 'p';
- chmod(line, 0666);
- chown(line, 0, 0);
-} /* end of rmut */
-#endif /* CRAY */
-
-#if defined(__hpux) && !defined(HAVE_UTMPX_H)
-static void
-rmut (char *line)
-{
- struct utmp utmp;
- struct utmp *utptr;
- int fd; /* for /etc/wtmp */
-
- utmp.ut_type = USER_PROCESS;
- strncpy(utmp.ut_line, clean_ttyname(line), sizeof(utmp.ut_line));
- setutent();
- utptr = getutline(&utmp);
- /* write it out only if it exists */
- if (utptr) {
- utptr->ut_type = DEAD_PROCESS;
- utptr->ut_time = time(NULL);
- pututline(utptr);
- /* set wtmp entry if wtmp file exists */
- if ((fd = open(wtmpf, O_WRONLY | O_APPEND)) >= 0) {
- write(fd, utptr, sizeof(utmp));
- close(fd);
- }
- }
- endutent();
-
- chmod(line, 0666);
- chown(line, 0, 0);
- line[14] = line[13];
- line[13] = line[12];
- line[8] = 'm';
- line[9] = '/';
- line[10] = 'p';
- line[11] = 't';
- line[12] = 'y';
- chmod(line, 0666);
- chown(line, 0, 0);
-}
-#endif
-
-/*
- * cleanup()
- *
- * This is the routine to call when we are all through, to
- * clean up anything that needs to be cleaned up.
- */
-
-#ifdef PARENT_DOES_UTMP
-
-void
-cleanup(int sig)
-{
-#ifdef _CRAY
- static int incleanup = 0;
- int t;
- int child_status; /* status of child process as returned by waitpid */
- int flags = WNOHANG|WUNTRACED;
-
- /*
- * 1: Pick up the zombie, if we are being called
- * as the signal handler.
- * 2: If we are a nested cleanup(), return.
- * 3: Try to clean up TMPDIR.
- * 4: Fill in utmp with shutdown of process.
- * 5: Close down the network and pty connections.
- * 6: Finish up the TMPDIR cleanup, if needed.
- */
- if (sig == SIGCHLD) {
- while (waitpid(-1, &child_status, flags) > 0)
- ; /* VOID */
- /* Check if the child process was stopped
- * rather than exited. We want cleanup only if
- * the child has died.
- */
- if (WIFSTOPPED(child_status)) {
- return;
- }
- }
- t = sigblock(sigmask(SIGCHLD));
- if (incleanup) {
- sigsetmask(t);
- return;
- }
- incleanup = 1;
- sigsetmask(t);
-
- t = cleantmp(&wtmp);
- setutent(); /* just to make sure */
-#endif /* CRAY */
- rmut(line);
- close(ourpty);
- shutdown(net, 2);
-#ifdef _CRAY
- if (t == 0)
- cleantmp(&wtmp);
-#endif /* CRAY */
- exit(1);
-}
-
-#else /* PARENT_DOES_UTMP */
-
-void
-cleanup(int sig)
-{
-#if defined(HAVE_UTMPX_H) || !defined(HAVE_LOGWTMP)
- rmut();
-#ifdef HAVE_VHANGUP
-#ifndef __sgi
- vhangup(); /* XXX */
-#endif
-#endif
-#else
- char *p;
-
- p = line + sizeof("/dev/") - 1;
- if (logout(p))
- logwtmp(p, "", "");
- chmod(line, 0666);
- chown(line, 0, 0);
- *p = 'p';
- chmod(line, 0666);
- chown(line, 0, 0);
-#endif
- shutdown(net, 2);
- _exit(1);
-}
-
-#endif /* PARENT_DOES_UTMP */
-
-#ifdef PARENT_DOES_UTMP
-/*
- * _utmp_sig_rcv
- * utmp_sig_init
- * utmp_sig_wait
- * These three functions are used to coordinate the handling of
- * the utmp file between the server and the soon-to-be-login shell.
- * The server actually creates the utmp structure, the child calls
- * utmp_sig_wait(), until the server calls utmp_sig_notify() and
- * signals the future-login shell to proceed.
- */
-static int caught=0; /* NZ when signal intercepted */
-static void (*func)(); /* address of previous handler */
-
-void
-_utmp_sig_rcv(sig)
- int sig;
-{
- caught = 1;
- signal(SIGUSR1, func);
-}
-
-void
-utmp_sig_init()
-{
- /*
- * register signal handler for UTMP creation
- */
- if ((int)(func = signal(SIGUSR1, _utmp_sig_rcv)) == -1)
- fatalperror(net, "telnetd/signal");
-}
-
-void
-utmp_sig_reset()
-{
- signal(SIGUSR1, func); /* reset handler to default */
-}
-
-# ifdef __hpux
-# define sigoff() /* do nothing */
-# define sigon() /* do nothing */
-# endif
-
-void
-utmp_sig_wait()
-{
- /*
- * Wait for parent to write our utmp entry.
- */
- sigoff();
- while (caught == 0) {
- pause(); /* wait until we get a signal (sigon) */
- sigoff(); /* turn off signals while we check caught */
- }
- sigon(); /* turn on signals again */
-}
-
-void
-utmp_sig_notify(pid)
-{
- kill(pid, SIGUSR1);
-}
-
-#ifdef _CRAY
-static int gotsigjob = 0;
-
- /*ARGSUSED*/
-void
-sigjob(sig)
- int sig;
-{
- int jid;
- struct jobtemp *jp;
-
- while ((jid = waitjob(NULL)) != -1) {
- if (jid == 0) {
- return;
- }
- gotsigjob++;
- jobend(jid, NULL, NULL);
- }
-}
-
-/*
- * jid_getutid:
- * called by jobend() before calling cleantmp()
- * to find the correct $TMPDIR to cleanup.
- */
-
-struct utmp *
-jid_getutid(jid)
- int jid;
-{
- struct utmp *cur = NULL;
-
- setutent(); /* just to make sure */
- while (cur = getutent()) {
- if ( (cur->ut_type != NULL) && (jid == cur->ut_jid) ) {
- return(cur);
- }
- }
-
- return(0);
-}
-
-/*
- * Clean up the TMPDIR that login created.
- * The first time this is called we pick up the info
- * from the utmp. If the job has already gone away,
- * then we'll clean up and be done. If not, then
- * when this is called the second time it will wait
- * for the signal that the job is done.
- */
-int
-cleantmp(wtp)
- struct utmp *wtp;
-{
- struct utmp *utp;
- static int first = 1;
- int mask, omask, ret;
- extern struct utmp *getutid (const struct utmp *_Id);
-
-
- mask = sigmask(WJSIGNAL);
-
- if (first == 0) {
- omask = sigblock(mask);
- while (gotsigjob == 0)
- sigpause(omask);
- return(1);
- }
- first = 0;
- setutent(); /* just to make sure */
-
- utp = getutid(wtp);
- if (utp == 0) {
- syslog(LOG_ERR, "Can't get /etc/utmp entry to clean TMPDIR");
- return(-1);
- }
- /*
- * Nothing to clean up if the user shell was never started.
- */
- if (utp->ut_type != USER_PROCESS || utp->ut_jid == 0)
- return(1);
-
- /*
- * Block the WJSIGNAL while we are in jobend().
- */
- omask = sigblock(mask);
- ret = jobend(utp->ut_jid, utp->ut_tpath, utp->ut_user);
- sigsetmask(omask);
- return(ret);
-}
-
-/*
- * jobend
- * Assumes that if path is not NULL, then user is also
- * not NULL.
- */
-int
-jobend(jid, path, user)
- int jid;
- char *path;
- char *user;
-{
- static int saved_jid = 0;
- static int pty_saved_jid = 0;
- static char saved_path[sizeof(wtmp.ut_tpath)+1];
- static char saved_user[sizeof(wtmp.ut_user)+1];
-
- /*
- * this little piece of code comes into play
- * only when ptyreconnect is used to reconnect
- * to an previous session.
- *
- * this is the only time when the
- * "saved_jid != jid" code is executed.
- */
-
- if ( saved_jid && saved_jid != jid ) {
- if (!path) { /* called from signal handler */
- pty_saved_jid = jid;
- } else {
- pty_saved_jid = saved_jid;
- }
- }
-
- if (path) {
- strncpy(saved_path, path, sizeof(saved_path) - 1);
- strncpy(saved_user, path, sizeof(saved_user) - 1);
- saved_path[sizeof(saved_path) - 1] = '\0';
- saved_user[sizeof(saved_user) - 1] = '\0';
- }
- if (saved_jid == 0) {
- saved_jid = jid;
- return(0);
- }
-
- /* if the jid has changed, get the correct entry from the utmp file */
-
- if ( saved_jid != jid ) {
- struct utmp *utp = NULL;
- struct utmp *jid_getutid();
-
- utp = jid_getutid(pty_saved_jid);
-
- if (utp == 0) {
- syslog(LOG_ERR, "Can't get /etc/utmp entry to clean TMPDIR");
- return(-1);
- }
-
- cleantmpdir(jid, utp->ut_tpath, utp->ut_user);
- return(1);
- }
-
- cleantmpdir(jid, saved_path, saved_user);
- return(1);
-}
-
-/*
- * Fork a child process to clean up the TMPDIR
- */
-cleantmpdir(jid, tpath, user)
- int jid;
- char *tpath;
- char *user;
-{
- switch(fork()) {
- case -1:
- syslog(LOG_ERR, "TMPDIR cleanup(%s): fork() failed: %m",
- tpath);
- break;
- case 0:
- execl(CLEANTMPCMD, CLEANTMPCMD, user, tpath, (char *)NULL);
- syslog(LOG_ERR, "TMPDIR cleanup(%s): execl(%s) failed: %m",
- tpath, CLEANTMPCMD);
- exit(1);
- default:
- /*
- * Forget about child. We will exit, and
- * /etc/init will pick it up.
- */
- break;
- }
-}
-#endif /* CRAY */
-#endif /* defined(PARENT_DOES_UTMP) */
diff --git a/libexec/telnetd/telnetd.8 b/libexec/telnetd/telnetd.8
deleted file mode 100644
index cdba3a0ed28..00000000000
--- a/libexec/telnetd/telnetd.8
+++ /dev/null
@@ -1,537 +0,0 @@
-.\" $OpenBSD: telnetd.8,v 1.33 2003/08/08 09:26:03 jmc 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.
-.\"
-.\" @(#)telnetd.8 8.4 (Berkeley) 6/1/94
-.\"
-.Dd June 1, 1994
-.Dt TELNETD 8
-.Os
-.Sh NAME
-.Nm telnetd
-.Nd DARPA
-.Tn TELNET
-protocol server
-.Sh SYNOPSIS
-.Nm telnetd
-.Bk -words
-.Op Fl BUhkln
-.Op Fl D Ar debugmode
-.Op Fl S Ar tos
-.Op Fl X Ar authtype
-.Op Fl a Ar authmode
-.Op Fl g Ar gettyent
-.Op Fl r Ar lowpty-highpty
-.Op Fl u Ar len
-.Op Fl debug
-.Op Fl L Ar /bin/login
-.Op Fl y
-.Op Ar port
-.Ek
-.Sh DESCRIPTION
-The
-.Nm telnetd
-command is a server which supports the
-.Tn DARPA
-standard
-.Tn TELNET
-virtual terminal protocol.
-.Nm Telnetd
-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 telnetd
-manually, instead of through
-.Xr inetd 8 .
-If started up this way,
-.Ar port
-may be specified to run
-.Nm telnetd
-on an alternate
-.Tn TCP
-port number.
-.Pp
-The
-.Nm telnetd
-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 Kerberos authentication.
-Note that this option is only useful if
-.Nm telnetd
-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 Kerberos 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 Kerberos 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 otp
-.\" Only allow Kerberos authenticated connections (as with
-.\" .Fl a
-.\" .Cm user )
-.\" and also logins with one-time passwords (OTPs).
-.\" This option will call login with an option so that only OTPs are accepted.
-.\" The user can of course still type secret information at the prompt.
-.It none
-This is the default state.
-Kerberos authentication information is not required.
-If no or insufficient authentication information
-is provided, then traditional cleartext passwords will be used.
-.It off
-This disables the authentication code, and cleartext password will be used.
-.El
-.It Fl B
-Ignored.
-.It Fl D Ar debugmode
-This option may be used for debugging purposes.
-This allows
-.Nm telnetd
-to print out debugging information
-to the connection, allowing the user to see what
-.Nm telnetd
-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 telnetd .
-.It Cm ptydata
-Displays data written to the pty.
-.It Cm exercise
-Has not been implemented yet.
-.El
-.It Fl h
-Disables the printing of host-specific information before
-login has been completed.
-.It Fl l
-Ignored.
-.It Fl n
-Disable
-.Dv TCP
-keep-alives.
-Normally
-.Nm telnetd
-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 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
-.Dq default.
-.It Fl r Ar lowpty-highpty
-This option is only enabled when
-.Nm telnetd
-is compiled for
-.Dv UNICOS .
-It specifies an inclusive range of pseudo-terminal devices to
-use.
-If the system has sysconf variable
-.Dv _SC_CRAY_NPTY
-configured, the default pty search range is 0 to
-.Dv _SC_CRAY_NPTY ;
-otherwise, the default range is 0 to 128.
-Either
-.Ar lowpty
-or
-.Ar highpty
-may be omitted to allow changing
-either end of the search range.
-If
-.Ar lowpty
-is omitted, the - character is still required so that
-.Nm telnetd
-can differentiate
-.Ar highpty
-from
-.Ar lowpty .
-.It Fl S Ar tos
-.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 telnetd
-to refuse connections from addresses that
-cannot be mapped back into a symbolic name
-via the
-.Xr gethostbyaddr 3
-routine.
-.It Fl X Ar authtype
-This option is only valid if
-.Nm telnetd
-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 telnetd .
-.It Fl L Ar pathname
-Specify pathname to an alternative login program.
-.It Fl y
-Makes
-.Nm telnetd
-not warn when a user is trying to login with cleartext
-passwords.
-.El
-.Pp
-.Nm Telnetd
-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 Telnetd
-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 telnetd
-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
-.Dq cooked
-mode, and with
-.Dv XTABS and
-.Dv CRMOD
-enabled (see
-.Xr tty 4 ) .
-.Pp
-.Nm Telnetd
-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
-.Nm 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
-.Nm 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
-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, 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 telnetd
-Kerberos is enabled, and
-indicates a willingness to decrypt
-the data stream.
-.El
-.Pp
-.Nm Telnetd
-has support for enabling remotely the following
-.Tn TELNET
-options:
-.Bl -tag -width "DO AUTHENTICATION"
-.It "DO BINARY"
-Sent to indicate that
-.Nm 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 4.2BSD
-.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 X11 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 telnetd
-is compiled with support for linemode, and
-requests that the client do line by line processing.
-.It "DO TIMING-MARK"
-Only sent if
-.Nm telnetd
-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 telnetd
-Kerberos authentication is enabled, and
-indicates a willingness to receive authentication
-information for automatic login.
-.It "DO ENCRYPT"
-Only sent if
-.Nm telnetd
-Kerberos is enabled, and
-indicates a willingness to decrypt
-the data stream.
-.El
-.Sh FILES
-.Bl -tag -width /etc/services -compact
-.It Pa /etc/services
-.It Pa /etc/inittab
-(UNICOS systems only)
-.It Pa /etc/iptos
-(if supported)
-.El
-.Sh SEE ALSO
-.Xr login 1 ,
-.Xr telnet 1
-.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 4.2 BSD
-.Xr telnet 1 ,
-.Nm telnetd
-performs some dubious protocol exchanges to try to discover if the remote
-client is, in fact, a 4.2 BSD
-.Xr telnet 1 .
-.Pp
-Binary mode
-has no common interpretation except between similar operating systems
-(Unix in this case).
-.Pp
-The terminal type name received from the remote client is converted to
-lower case.
-.Pp
-.Nm Telnetd
-never sends
-.Tn TELNET
-.Dv IAC GA
-(go ahead) commands.
diff --git a/libexec/telnetd/telnetd.c b/libexec/telnetd/telnetd.c
deleted file mode 100644
index e31286bcb50..00000000000
--- a/libexec/telnetd/telnetd.c
+++ /dev/null
@@ -1,1398 +0,0 @@
-/*
- * 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 "telnetd.h"
-#include <sys/socket.h>
-#include <netdb.h>
-#include <fcntl.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-
-/* RCSID("$KTH: telnetd.c,v 1.64 2001/02/08 16:06:27 assar Exp $"); */
-
-#ifdef _SC_CRAY_SECURE_SYS
-#include <sys/sysv.h>
-#include <sys/secdev.h>
-#include <sys/secparm.h>
-#include <sys/usrv.h>
-int secflag;
-char tty_dev[16];
-struct secdev dv;
-struct sysv sysv;
-struct socksec ss;
-#endif /* _SC_CRAY_SECURE_SYS */
-
-#ifndef ENCRYPTION
-#define encrypt_delay() 0
-#endif
-
-#ifdef AUTHENTICATION
-int auth_level = 0;
-#endif
-
-extern int utmp_len;
-int registerd_host_only = 0;
-
-#ifdef STREAMSPTY
-# include <stropts.h>
-# include <termios.h>
-#ifdef HAVE_SYS_UIO_H
-#include <sys/uio.h>
-#endif /* HAVE_SYS_UIO_H */
-#ifdef HAVE_SYS_STREAM_H
-#include <sys/stream.h>
-#endif
-#ifdef _AIX
-#include <sys/termio.h>
-#endif
-# ifdef HAVE_SYS_STRTTY_H
-# include <sys/strtty.h>
-# endif
-# ifdef HAVE_SYS_STR_TTY_H
-# include <sys/str_tty.h>
-# endif
-/* make sure we don't get the bsd version */
-/* what is this here for? solaris? /joda */
-# ifdef HAVE_SYS_TTY_H
-# include "/usr/include/sys/tty.h"
-# endif
-# ifdef HAVE_SYS_PTYVAR_H
-# include <sys/ptyvar.h>
-# endif
-
-/*
- * Because of the way ptyibuf is used with streams messages, we need
- * ptyibuf+1 to be on a full-word boundary. The following weirdness
- * is simply to make that happen.
- */
-long ptyibufbuf[BUFSIZ/sizeof(long)+1];
-char *ptyibuf = ((char *)&ptyibufbuf[1])-1;
-char *ptyip = ((char *)&ptyibufbuf[1])-1;
-char ptyibuf2[BUFSIZ];
-unsigned char ctlbuf[BUFSIZ];
-struct strbuf strbufc, strbufd;
-
-int readstream(int, char*, int);
-
-#else /* ! STREAMPTY */
-
-/*
- * I/O data buffers,
- * pointers, and counters.
- */
-char ptyibuf[BUFSIZ], *ptyip = ptyibuf;
-char ptyibuf2[BUFSIZ];
-
-#endif /* ! STREAMPTY */
-
-int hostinfo = 1; /* do we print login banner? */
-
-#ifdef _CRAY
-extern int newmap; /* nonzero if \n maps to ^M^J */
-int lowpty = 0, highpty; /* low, high pty numbers */
-#endif /* CRAY */
-
-int debug = 0;
-int keepalive = 1;
-char *progname;
-char *gettyent = "default";
-char *gettytab[2] = { "/etc/gettytab", NULL };
-
-static void usage (void);
-
-/*
- * The string to pass to getopt(). We do it this way so
- * that only the actual options that we support will be
- * passed off to getopt().
- */
-char valid_opts[] = "Bd:g:hklnS:u:UL:y"
-#ifdef AUTHENTICATION
- "a:X:z"
-#endif
-#ifdef DIAGNOSTICS
- "D:"
-#endif
-#ifdef _CRAY
- "r:"
-#endif
- ;
-
-static void doit(struct sockaddr*, int);
-
-int
-main(int argc, char **argv)
-{
- struct sockaddr_storage __ss;
- struct sockaddr *sa = (struct sockaddr *)&__ss;
- int on = 1;
- socklen_t sa_size;
- int ch;
-#if defined(IPPROTO_IP) && defined(IP_TOS)
- int tos = -1;
-#endif
-#ifdef ENCRYPTION
- extern int des_check_key;
- des_check_key = 1; /* Kludge for Mac NCSA telnet 2.6 /bg */
-#endif
- pfrontp = pbackp = ptyobuf;
- netip = netibuf;
- nfrontp = nbackp = netobuf;
-
- progname = *argv;
-#ifdef ENCRYPTION
- nclearto = 0;
-#endif
-
-#ifdef _CRAY
- /*
- * Get number of pty's before trying to process options,
- * which may include changing pty range.
- */
- highpty = getnpty();
-#endif /* CRAY */
-
- while ((ch = getopt(argc, argv, valid_opts)) != -1) {
- switch(ch) {
-
-#ifdef AUTHENTICATION
- case 'a':
- /*
- * Check for required authentication level
- */
- if (strcmp(optarg, "debug") == 0) {
- auth_debug_mode = 1;
- } else if (strcasecmp(optarg, "none") == 0) {
- auth_level = 0;
- } else if (strcasecmp(optarg, "other") == 0) {
- auth_level = AUTH_OTHER;
- } else if (strcasecmp(optarg, "user") == 0) {
- auth_level = AUTH_USER;
- } else if (strcasecmp(optarg, "valid") == 0) {
- auth_level = AUTH_VALID;
- } else if (strcasecmp(optarg, "off") == 0) {
- /*
- * This hack turns off authentication
- */
- auth_level = -1;
- } else {
- fprintf(stderr,
- "telnetd: unknown authorization level for -a\n");
- }
- break;
-#endif /* AUTHENTICATION */
-
- case 'B': /* BFTP mode is not supported any more */
- break;
- case 'd':
- if (strcmp(optarg, "ebug") == 0) {
- debug++;
- break;
- }
- usage();
- /* NOTREACHED */
- break;
-
-#ifdef DIAGNOSTICS
- case 'D':
- /*
- * Check for desired diagnostics capabilities.
- */
- if (!strcmp(optarg, "report")) {
- diagnostic |= TD_REPORT|TD_OPTIONS;
- } else if (!strcmp(optarg, "exercise")) {
- diagnostic |= TD_EXERCISE;
- } else if (!strcmp(optarg, "netdata")) {
- diagnostic |= TD_NETDATA;
- } else if (!strcmp(optarg, "ptydata")) {
- diagnostic |= TD_PTYDATA;
- } else if (!strcmp(optarg, "options")) {
- diagnostic |= TD_OPTIONS;
- } else {
- usage();
- /* NOT REACHED */
- }
- break;
-#endif /* DIAGNOSTICS */
-
-
- case 'g':
- gettyent = optarg;
- break;
-
- case 'h':
- hostinfo = 0;
- break;
-
- case 'k': /* Linemode is not supported any more */
- case 'l':
- break;
-
- case 'n':
- keepalive = 0;
- break;
-
-#ifdef _CRAY
- case 'r':
- {
- char *strchr();
- char *c;
-
- /*
- * Allow the specification of alterations
- * to the pty search range. It is legal to
- * specify only one, and not change the
- * other from its default.
- */
- c = strchr(optarg, '-');
- if (c) {
- *c++ = '\0';
- highpty = atoi(c);
- }
- if (*optarg != '\0')
- lowpty = atoi(optarg);
- if ((lowpty > highpty) || (lowpty < 0) ||
- (highpty > 32767)) {
- usage();
- /* NOT REACHED */
- }
- break;
- }
-#endif /* CRAY */
-
- case 'S':
-#ifdef HAVE_PARSETOS
- if ((tos = parsetos(optarg, "tcp")) < 0)
- fprintf(stderr, "%s%s%s\n",
- "telnetd: Bad TOS argument '", optarg,
- "'; will try to use default TOS");
-#else
- fprintf(stderr, "%s%s\n", "TOS option unavailable; ",
- "-S flag not supported\n");
-#endif
- break;
-
- case 'u': {
- char *eptr;
-
- utmp_len = strtol(optarg, &eptr, 0);
- if (optarg == eptr)
- fprintf(stderr, "telnetd: unknown utmp len (%s)\n", optarg);
- break;
- }
-
- case 'U':
- registerd_host_only = 1;
- break;
-
-#ifdef AUTHENTICATION
- case 'X':
- /*
- * Check for invalid authentication types
- */
- auth_disable_name(optarg);
- break;
-#endif
- case 'y':
- no_warn = 1;
- break;
-#ifdef AUTHENTICATION
- case 'z':
- log_unauth = 1;
- break;
-
-#endif /* AUTHENTICATION */
-
- case 'L':
- new_login = optarg;
- break;
-
- default:
- fprintf(stderr, "telnetd: %c: unknown option\n", ch);
- /* FALLTHROUGH */
- case '?':
- usage();
- /* NOTREACHED */
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (debug) {
- int port = 0;
- struct servent *sp;
-
- if (argc > 1) {
- usage ();
- } else if (argc == 1) {
- sp = getservbyname (*argv, "tcp");
- if (sp)
- port = sp->s_port;
- else
- port = htons(atoi(*argv));
- } else {
- sp = getservbyname ("telnet", "tcp");
- port = sp ? sp->s_port : htons(23);
- }
- mini_inetd (port);
- } else if (argc > 0) {
- usage();
- /* NOT REACHED */
- }
-
-#ifdef _SC_CRAY_SECURE_SYS
- secflag = sysconf(_SC_CRAY_SECURE_SYS);
-
- /*
- * Get socket's security label
- */
- if (secflag) {
- socklen_t szss = sizeof(ss);
- int sock_multi;
- socklen_t szi = sizeof(int);
-
- memset(&dv, 0, sizeof(dv));
-
- if (getsysv(&sysv, sizeof(struct sysv)) != 0)
- fatalperror(net, "getsysv");
-
- /*
- * Get socket security label and set device values
- * {security label to be set on ttyp device}
- */
-#ifdef SO_SEC_MULTI /* 8.0 code */
- if ((getsockopt(0, SOL_SOCKET, SO_SECURITY,
- (void *)&ss, &szss) < 0) ||
- (getsockopt(0, SOL_SOCKET, SO_SEC_MULTI,
- (void *)&sock_multi, &szi) < 0))
- fatalperror(net, "getsockopt");
- else {
- dv.dv_actlvl = ss.ss_actlabel.lt_level;
- dv.dv_actcmp = ss.ss_actlabel.lt_compart;
- if (!sock_multi) {
- dv.dv_minlvl = dv.dv_maxlvl = dv.dv_actlvl;
- dv.dv_valcmp = dv.dv_actcmp;
- } else {
- dv.dv_minlvl = ss.ss_minlabel.lt_level;
- dv.dv_maxlvl = ss.ss_maxlabel.lt_level;
- dv.dv_valcmp = ss.ss_maxlabel.lt_compart;
- }
- dv.dv_devflg = 0;
- }
-#else /* SO_SEC_MULTI */ /* 7.0 code */
- if (getsockopt(0, SOL_SOCKET, SO_SECURITY,
- (void *)&ss, &szss) >= 0) {
- dv.dv_actlvl = ss.ss_slevel;
- dv.dv_actcmp = ss.ss_compart;
- dv.dv_minlvl = ss.ss_minlvl;
- dv.dv_maxlvl = ss.ss_maxlvl;
- dv.dv_valcmp = ss.ss_maxcmp;
- }
-#endif /* SO_SEC_MULTI */
- }
-#endif /* _SC_CRAY_SECURE_SYS */
-
- openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
- sa_size = sizeof (__ss);
- if (getpeername(STDIN_FILENO, sa, &sa_size) < 0) {
- fprintf(stderr, "%s: ", progname);
- perror("getpeername");
- _exit(1);
- }
- if (keepalive &&
- setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
- (void *)&on, sizeof (on)) < 0) {
- syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
- }
-
-#if defined(IPPROTO_IP) && defined(IP_TOS) && defined(HAVE_SETSOCKOPT)
- {
-# ifdef HAVE_GETTOSBYNAME
- struct tosent *tp;
- if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
- tos = tp->t_tos;
-# endif
- if (tos < 0)
- tos = 020; /* Low Delay bit */
- if (tos
- && sa->sa_family == AF_INET
- && (setsockopt(STDIN_FILENO, IPPROTO_IP, IP_TOS,
- (void *)&tos, sizeof(tos)) < 0)
- && (errno != ENOPROTOOPT) )
- syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
- }
-#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */
- net = STDIN_FILENO;
- doit(sa, sa_size);
- /* NOTREACHED */
- return 0;
-} /* end of main */
-
-static void
-usage(void)
-{
- fprintf(stderr, "Usage: telnetd");
-#ifdef AUTHENTICATION
- fprintf(stderr, " [-a (debug|other|user|valid|off|none)]\n\t");
-#endif
- fprintf(stderr, " [-debug]");
-#ifdef DIAGNOSTICS
- fprintf(stderr, " [-D (options|report|exercise|netdata|ptydata)]\n\t");
-#endif
-#ifdef AUTHENTICATION
- fprintf(stderr, " [-edebug]");
-#endif
- fprintf(stderr, " [-h]");
- fprintf(stderr, " [-L login]");
- fprintf(stderr, " [-n]");
-#ifdef _CRAY
- fprintf(stderr, " [-r[lowpty]-[highpty]]");
-#endif
- fprintf(stderr, "\n\t");
-#ifdef HAVE_GETTOSBYNAME
- fprintf(stderr, " [-S tos]");
-#endif
-#ifdef AUTHENTICATION
- fprintf(stderr, " [-X auth-type] [-y] [-z]");
-#endif
- fprintf(stderr, " [-u utmp_hostname_length] [-U]");
- fprintf(stderr, " [port]\n");
- exit(1);
-}
-
-/*
- * getterminaltype
- *
- * Ask the other end to send along its terminal type and speed.
- * Output is the variable terminaltype filled in.
- */
-static unsigned char ttytype_sbbuf[] = {
- IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE
-};
-
-int
-getterminaltype(char *name, size_t name_sz)
-{
- int retval = -1;
-
- settimer(baseline);
-#ifdef AUTHENTICATION
- /*
- * Handle the Authentication option before we do anything else.
- */
- send_do(TELOPT_AUTHENTICATION, 1);
- while (his_will_wont_is_changing(TELOPT_AUTHENTICATION))
- ttloop();
- if (his_state_is_will(TELOPT_AUTHENTICATION)) {
- retval = auth_wait(name, name_sz);
- }
-#endif
-
-#ifdef ENCRYPTION
- send_will(TELOPT_ENCRYPT, 1);
- send_do(TELOPT_ENCRYPT, 1); /* esc@magic.fi */
-#endif
- send_do(TELOPT_TTYPE, 1);
- send_do(TELOPT_TSPEED, 1);
- send_do(TELOPT_XDISPLOC, 1);
- send_do(TELOPT_NEW_ENVIRON, 1);
- send_do(TELOPT_OLD_ENVIRON, 1);
- while (
-#ifdef ENCRYPTION
- his_do_dont_is_changing(TELOPT_ENCRYPT) ||
-#endif
- his_will_wont_is_changing(TELOPT_TTYPE) ||
- his_will_wont_is_changing(TELOPT_TSPEED) ||
- his_will_wont_is_changing(TELOPT_XDISPLOC) ||
- his_will_wont_is_changing(TELOPT_NEW_ENVIRON) ||
- his_will_wont_is_changing(TELOPT_OLD_ENVIRON)) {
- ttloop();
- }
-#ifdef ENCRYPTION
- /*
- * Wait for the negotiation of what type of encryption we can
- * send with. If autoencrypt is not set, this will just return.
- */
- if (his_state_is_will(TELOPT_ENCRYPT)) {
- encrypt_wait();
- }
-#endif
- if (his_state_is_will(TELOPT_TSPEED)) {
- static unsigned char sb[] =
- { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
-
- telnet_net_write (sb, sizeof sb);
- DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
- }
- if (his_state_is_will(TELOPT_XDISPLOC)) {
- static unsigned char sb[] =
- { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
-
- telnet_net_write (sb, sizeof sb);
- DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
- }
- if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
- static unsigned char sb[] =
- { IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE };
-
- telnet_net_write (sb, sizeof sb);
- DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
- }
- else if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
- static unsigned char sb[] =
- { IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE };
-
- telnet_net_write (sb, sizeof sb);
- DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
- }
- if (his_state_is_will(TELOPT_TTYPE)) {
-
- telnet_net_write (ttytype_sbbuf, sizeof ttytype_sbbuf);
- DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
- sizeof ttytype_sbbuf - 2););
- }
- if (his_state_is_will(TELOPT_TSPEED)) {
- while (sequenceIs(tspeedsubopt, baseline))
- ttloop();
- }
- if (his_state_is_will(TELOPT_XDISPLOC)) {
- while (sequenceIs(xdisplocsubopt, baseline))
- ttloop();
- }
- if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
- while (sequenceIs(environsubopt, baseline))
- ttloop();
- }
- if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
- while (sequenceIs(oenvironsubopt, baseline))
- ttloop();
- }
- if (his_state_is_will(TELOPT_TTYPE)) {
- char first[256], last[256];
-
- while (sequenceIs(ttypesubopt, baseline))
- ttloop();
-
- /*
- * If the other side has already disabled the option, then
- * we have to just go with what we (might) have already gotten.
- */
- if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) {
- strlcpy(first, terminaltype, sizeof(first));
- for(;;) {
- /*
- * Save the unknown name, and request the next name.
- */
- strlcpy(last, terminaltype, sizeof(last));
- _gettermname();
- if (terminaltypeok(terminaltype))
- break;
- if ((strncmp(last, terminaltype, sizeof(last)) == 0) ||
- his_state_is_wont(TELOPT_TTYPE)) {
- /*
- * We've hit the end. If this is the same as
- * the first name, just go with it.
- */
- if (strncmp(first, terminaltype, sizeof(first)) == 0)
- break;
- /*
- * Get the terminal name one more time, so that
- * RFC1091 compliant telnets will cycle back to
- * the start of the list.
- */
- _gettermname();
- if (strncmp(first, terminaltype, sizeof(first)) != 0)
- strlcpy(terminaltype, first, sizeof(terminaltype));
- break;
- }
- }
- }
- }
- return(retval);
-} /* end of getterminaltype */
-
-void
-_gettermname(void)
-{
- /*
- * If the client turned off the option,
- * we can't send another request, so we
- * just return.
- */
- if (his_state_is_wont(TELOPT_TTYPE))
- return;
- settimer(baseline);
- telnet_net_write (ttytype_sbbuf, sizeof ttytype_sbbuf);
- DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
- sizeof ttytype_sbbuf - 2););
- while (sequenceIs(ttypesubopt, baseline))
- ttloop();
-}
-
-int
-terminaltypeok(char *s)
-{
- return 1;
-}
-
-
-char host_name[MAXHOSTNAMELEN];
-char remote_host_name[MAXHOSTNAMELEN];
-char remote_utmp_name[MAXHOSTNAMELEN];
-
-/*
- * Get a pty, scan input lines.
- */
-static void
-doit(struct sockaddr *who, int who_len)
-{
- int level;
- int ptynum;
- char user_name[256];
- int error;
-
- /*
- * Find an available pty to use.
- */
- ourpty = getpty(&ptynum);
- if (ourpty < 0)
- fatal(net, "All network ports in use");
-
-#ifdef _SC_CRAY_SECURE_SYS
- /*
- * set ttyp line security label
- */
- if (secflag) {
- char slave_dev[16];
-
- snprintf(tty_dev, sizeof(tty_dev), "/dev/pty/%03d", ptynum);
- if (setdevs(tty_dev, &dv) < 0)
- fatal(net, "cannot set pty security");
- snprintf(slave_dev, sizeof(slave_dev), "/dev/ttyp%03d", ptynum);
- if (setdevs(slave_dev, &dv) < 0)
- fatal(net, "cannot set tty security");
- }
-#endif /* _SC_CRAY_SECURE_SYS */
-
- error = getnameinfo (who, who_len,
- remote_host_name,
- sizeof(remote_host_name),
- NULL, 0,
- registerd_host_only ? NI_NAMEREQD : 0);
- if (error)
- fatal(net, "Couldn't resolve your address into a host name.\r\n\
-Please contact your net administrator");
-
- gethostname(host_name, sizeof (host_name));
-
- strlcpy (remote_utmp_name, remote_host_name, sizeof(remote_utmp_name));
-
- /* Only trim if too long (and possible) */
- if (strlen(remote_utmp_name) > utmp_len) {
- char *domain = strchr(host_name, '.');
- char *p = strchr(remote_utmp_name, '.');
- if (domain != NULL && p != NULL && (strcmp(p, domain) == 0))
- *p = '\0'; /* remove domain part */
- }
-
- /*
- * If hostname still doesn't fit utmp, use ipaddr.
- */
- if (strlen(remote_utmp_name) > utmp_len) {
- error = getnameinfo (who, who_len,
- remote_utmp_name,
- sizeof(remote_utmp_name),
- NULL, 0,
- NI_NUMERICHOST);
- if (error)
- fatal(net, "Couldn't get numeric address\r\n");
- }
-
-#ifdef AUTHENTICATION
- auth_encrypt_init(host_name, remote_host_name, "TELNETD", 1);
-#endif
-
- init_env();
- /*
- * get terminal type.
- */
- *user_name = 0;
- level = getterminaltype(user_name, sizeof(user_name));
- esetenv("TERM", terminaltype ? terminaltype : "network", 1);
-
-#ifdef _SC_CRAY_SECURE_SYS
- if (secflag) {
- if (setulvl(dv.dv_actlvl) < 0)
- fatal(net,"cannot setulvl()");
- if (setucmp(dv.dv_actcmp) < 0)
- fatal(net, "cannot setucmp()");
- }
-#endif /* _SC_CRAY_SECURE_SYS */
-
- /* begin server processing */
- my_telnet(net, ourpty, remote_host_name, remote_utmp_name,
- level, user_name);
- /*NOTREACHED*/
-} /* end of doit */
-
-/* output contents of /etc/issue.net, or /etc/issue */
-static void
-show_issue(void)
-{
- FILE *f;
- char buf[128];
- f = fopen("/etc/issue.net", "r");
- if(f == NULL)
- f = fopen("/etc/issue", "r");
- if(f){
- while(fgets(buf, sizeof(buf)-2, f)){
- size_t off = strcspn(buf, "\r\n");
- strlcpy(buf + off, "\r\n", sizeof(buf) - off);
- writenet((unsigned char*)buf, strlen(buf));
- }
- fclose(f);
- }
-}
-
-/*
- * Main loop. Select from pty and network, and
- * hand data to telnet receiver finite state machine.
- */
-void
-my_telnet(int f, int p, const char *host, const char *utmp_host,
- int level, char *autoname)
-{
- int on = 1;
- char *he;
- char *IM;
- char *buf;
- int nfd;
- int startslave_called = 0;
- time_t timeout;
- fd_set *ibits = NULL;
- fd_set *obits = NULL;
- fd_set *xbits = NULL;
- int setsize;
-
- /*
- * Initialize the slc mapping table.
- */
- get_slc_defaults();
-
- /*
- * Do some tests where it is desireable to wait for a response.
- * Rather than doing them slowly, one at a time, do them all
- * at once.
- */
- if (my_state_is_wont(TELOPT_SGA))
- send_will(TELOPT_SGA, 1);
- /*
- * Is the client side a 4.2 (NOT 4.3) system? We need to know this
- * because 4.2 clients are unable to deal with TCP urgent data.
- *
- * To find out, we send out a "DO ECHO". If the remote system
- * answers "WILL ECHO" it is probably a 4.2 client, and we note
- * that fact ("WILL ECHO" ==> that the client will echo what
- * WE, the server, sends it; it does NOT mean that the client will
- * echo the terminal input).
- */
- send_do(TELOPT_ECHO, 1);
-
- /*
- * Send along a couple of other options that we wish to negotiate.
- */
- send_do(TELOPT_NAWS, 1);
- send_will(TELOPT_STATUS, 1);
- flowmode = 1; /* default flow control state */
- restartany = -1; /* uninitialized... */
- send_do(TELOPT_LFLOW, 1);
-
- /*
- * Spin, waiting for a response from the DO ECHO. However,
- * some REALLY DUMB telnets out there might not respond
- * to the DO ECHO. So, we spin looking for NAWS, (most dumb
- * telnets so far seem to respond with WONT for a DO that
- * they don't understand...) because by the time we get the
- * response, it will already have processed the DO ECHO.
- * Kludge upon kludge.
- */
- while (his_will_wont_is_changing(TELOPT_NAWS))
- ttloop();
-
- /*
- * But...
- * The client might have sent a WILL NAWS as part of its
- * startup code; if so, we'll be here before we get the
- * response to the DO ECHO. We'll make the assumption
- * that any implementation that understands about NAWS
- * is a modern enough implementation that it will respond
- * to our DO ECHO request; hence we'll do another spin
- * waiting for the ECHO option to settle down, which is
- * what we wanted to do in the first place...
- */
- if (his_want_state_is_will(TELOPT_ECHO) &&
- his_state_is_will(TELOPT_NAWS)) {
- while (his_will_wont_is_changing(TELOPT_ECHO))
- ttloop();
- }
- /*
- * On the off chance that the telnet client is broken and does not
- * respond to the DO ECHO we sent, (after all, we did send the
- * DO NAWS negotiation after the DO ECHO, and we won't get here
- * until a response to the DO NAWS comes back) simulate the
- * receipt of a will echo. This will also send a WONT ECHO
- * to the client, since we assume that the client failed to
- * respond because it believes that it is already in DO ECHO
- * mode, which we do not want.
- */
- if (his_want_state_is_will(TELOPT_ECHO)) {
- DIAG(TD_OPTIONS,
- {output_data("td: simulating recv\r\n");
- });
- willoption(TELOPT_ECHO);
- }
-
- /*
- * Finally, to clean things up, we turn on our echo. This
- * will break stupid 4.2 telnets out of local terminal echo.
- */
-
- if (my_state_is_wont(TELOPT_ECHO))
- send_will(TELOPT_ECHO, 1);
-
-#ifdef TIOCPKT
-#ifdef STREAMSPTY
- if (!really_stream)
-#endif
- /*
- * Turn on packet mode
- */
- ioctl(p, TIOCPKT, (char *)&on);
-#endif
-
-
- /*
- * Call telrcv() once to pick up anything received during
- * terminal type negotiation, 4.2/4.3 determination, and
- * linemode negotiation.
- */
- telrcv();
-
- ioctl(f, FIONBIO, (char *)&on);
- ioctl(p, FIONBIO, (char *)&on);
-
-#if defined(SO_OOBINLINE) && defined(HAVE_SETSOCKOPT)
- setsockopt(net, SOL_SOCKET, SO_OOBINLINE,
- (void *)&on, sizeof on);
-#endif /* defined(SO_OOBINLINE) */
-
-#ifdef SIGTSTP
- signal(SIGTSTP, SIG_IGN);
-#endif
-#ifdef SIGTTOU
- /*
- * Ignoring SIGTTOU keeps the kernel from blocking us
- * in ttioct() in /sys/tty.c.
- */
- signal(SIGTTOU, SIG_IGN);
-#endif
-
- signal(SIGCHLD, cleanup);
-
-#ifdef TIOCNOTTY
- {
- int t;
- t = open(_PATH_TTY, O_RDWR);
- if (t >= 0) {
- ioctl(t, TIOCNOTTY, (char *)0);
- close(t);
- }
- }
-#endif
-
- show_issue();
- /*
- * Show banner that getty never gave.
- *
- * We put the banner in the pty input buffer. This way, it
- * gets carriage return null processing, etc., just like all
- * other pty --> client data.
- */
-
- if (getenv("USER"))
- hostinfo = 0;
-
- if (cgetent(&buf, gettytab, gettyent) >= 0) {
- char *HN;
-
- if (cgetstr(buf, "he", &he) <= 0)
- he = NULL;
- if (cgetstr(buf, "im", &IM) <= 0)
- IM = "";
- if (cgetstr(buf, "hn", &HN) > 0) {
- strlcpy(host_name, HN, sizeof host_name);
- free(HN);
- }
- cgetclose();
- } else {
- IM = DEFAULT_IM;
- he = NULL;
- }
- edithost(he, host_name);
- if (he)
- free(he);
- if (hostinfo && *IM)
- putf(IM, ptyibuf2);
- if (IM != DEFAULT_IM && *IM)
- free(IM);
-
- if (pcc)
- strncat(ptyibuf2, ptyip, pcc+1);
- ptyip = ptyibuf2;
- pcc = strlen(ptyip);
-
- DIAG(TD_REPORT, {
- output_data("td: Entering processing loop\r\n");
- });
-
-
- nfd = ((f > p) ? f : p) + 1;
- setsize = howmany(nfd, NFDBITS) * sizeof(fd_mask);
- ibits = malloc(setsize);
- obits = malloc(setsize);
- xbits = malloc(setsize);
- if (ibits == NULL || obits == NULL || xbits == NULL) {
- syslog(LOG_ERR, "Out of memory");
- exit(1);
- }
- timeout = time(NULL) + 5;
- for (;;) {
- int c;
-
- /* wait for encryption to be turned on, but don't wait
- indefinitely */
- if(!startslave_called && (!encrypt_delay() || timeout > time(NULL))){
- startslave_called = 1;
- startslave(host, utmp_host, level, autoname);
- }
-
- if (ncc < 0 && pcc < 0)
- break;
-
- memset(obits, 0, setsize);
- memset(ibits, 0, setsize);
- memset(xbits, 0, setsize);
-
- /*
- * Never look for input if there's still
- * stuff in the corresponding output buffer
- */
- if (nfrontp - nbackp || pcc > 0) {
- FD_SET(f, obits);
- } else {
- FD_SET(p, ibits);
- }
- if (pfrontp - pbackp || ncc > 0) {
- FD_SET(p, obits);
- } else {
- FD_SET(f, ibits);
- }
- if (!SYNCHing) {
- FD_SET(f, xbits);
- }
- if ((c = select(nfd, ibits, obits, xbits,
- (struct timeval *)0)) < 1) {
- if (c == -1) {
- if (errno == EINTR) {
- continue;
- }
- }
- sleep(5);
- continue;
- }
-
- /*
- * Any urgent data?
- */
- if (FD_ISSET(f, xbits)) {
- SYNCHing = 1;
- }
-
- /*
- * Something to read from the network...
- */
- if (FD_ISSET(f, ibits)) {
-#ifndef SO_OOBINLINE
- /*
- * In 4.2 (and 4.3 beta) systems, the
- * OOB indication and data handling in the kernel
- * is such that if two separate TCP Urgent requests
- * come in, one byte of TCP data will be overlaid.
- * This is fatal for Telnet, but we try to live
- * with it.
- *
- * In addition, in 4.2 (and...), a special protocol
- * is needed to pick up the TCP Urgent data in
- * the correct sequence.
- *
- * What we do is: if we think we are in urgent
- * mode, we look to see if we are "at the mark".
- * If we are, we do an OOB receive. If we run
- * this twice, we will do the OOB receive twice,
- * but the second will fail, since the second
- * time we were "at the mark", but there wasn't
- * any data there (the kernel doesn't reset
- * "at the mark" until we do a normal read).
- * Once we've read the OOB data, we go ahead
- * and do normal reads.
- *
- * There is also another problem, which is that
- * since the OOB byte we read doesn't put us
- * out of OOB state, and since that byte is most
- * likely the TELNET DM (data mark), we would
- * stay in the TELNET SYNCH (SYNCHing) state.
- * So, clocks to the rescue. If we've "just"
- * received a DM, then we test for the
- * presence of OOB data when the receive OOB
- * fails (and AFTER we did the normal mode read
- * to clear "at the mark").
- */
- if (SYNCHing) {
- int atmark;
-
- ioctl(f, SIOCATMARK, (char *)&atmark);
- if (atmark) {
- ncc = recv(f, netibuf, sizeof (netibuf), MSG_OOB);
- if ((ncc == -1) && (errno == EINVAL)) {
- ncc = read(f, netibuf, sizeof (netibuf));
- if (sequenceIs(didnetreceive, gotDM)) {
- SYNCHing = stilloob(f);
- }
- }
- } else {
- ncc = read(f, netibuf, sizeof (netibuf));
- }
- } else {
- ncc = read(f, netibuf, sizeof (netibuf));
- }
- settimer(didnetreceive);
-#else /* !defined(SO_OOBINLINE)) */
- ncc = read(net, netibuf, sizeof (netibuf));
-#endif /* !defined(SO_OOBINLINE)) */
- if (ncc < 0 && errno == EWOULDBLOCK)
- ncc = 0;
- else {
- if (ncc <= 0) {
- break;
- }
- netip = netibuf;
- }
- DIAG((TD_REPORT | TD_NETDATA), {
- output_data("td: netread %d chars\r\n", ncc);
- });
- DIAG(TD_NETDATA, printdata("nd", netip, ncc));
- }
-
- /*
- * Something to read from the pty...
- */
- if (FD_ISSET(p, ibits)) {
-#ifdef STREAMSPTY
- if (really_stream)
- pcc = readstream(p, ptyibuf, BUFSIZ);
- else
-#endif
- pcc = read(p, ptyibuf, BUFSIZ);
-
- /*
- * On some systems, if we try to read something
- * off the master side before the slave side is
- * opened, we get EIO.
- */
- if (pcc < 0 && (errno == EWOULDBLOCK ||
-#ifdef EAGAIN
- errno == EAGAIN ||
-#endif
- errno == EIO)) {
- pcc = 0;
- } else {
- if (pcc <= 0)
- break;
- if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) {
- netclear(); /* clear buffer back */
-#ifndef NO_URGENT
- /*
- * There are client telnets on some
- * operating systems get screwed up
- * royally if we send them urgent
- * mode data.
- */
- output_data ("%c%c", IAC, DM);
-
- neturg = nfrontp-1; /* off by one XXX */
- DIAG(TD_OPTIONS,
- printoption("td: send IAC", DM));
-
-#endif
- }
- if (his_state_is_will(TELOPT_LFLOW) &&
- (ptyibuf[0] &
- (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))) {
- int newflow =
- ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0;
- if (newflow != flowmode) {
- flowmode = newflow;
- output_data("%c%c%c%c%c%c",
- IAC, SB, TELOPT_LFLOW,
- flowmode ? LFLOW_ON
- : LFLOW_OFF,
- IAC, SE);
- DIAG(TD_OPTIONS, printsub('>',
- (unsigned char *)nfrontp-4,
- 4););
- }
- }
- pcc--;
- ptyip = ptyibuf+1;
- }
- }
-
- while (pcc > 0) {
- if ((&netobuf[BUFSIZ] - nfrontp) < 3)
- break;
- c = *ptyip++ & 0377, pcc--;
- if (c == IAC)
- *nfrontp++ = c;
- *nfrontp++ = c;
- if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) {
- if (pcc > 0 && ((*ptyip & 0377) == '\n')) {
- *nfrontp++ = *ptyip++ & 0377;
- pcc--;
- } else
- *nfrontp++ = '\0';
- }
- }
-
- if (FD_ISSET(f, obits) && (nfrontp - nbackp) > 0)
- netflush();
- if (ncc > 0)
- telrcv();
- if (FD_ISSET(p, obits) && (pfrontp - pbackp) > 0)
- ptyflush();
- }
- cleanup(0);
-}
-
-#ifndef TCSIG
-# ifdef TIOCSIG
-# define TCSIG TIOCSIG
-# endif
-#endif
-
-#ifdef STREAMSPTY
-
- int flowison = -1; /* current state of flow: -1 is unknown */
-
-int
-readstream(int p, char *ibuf, int bufsize)
-{
- int flags = 0;
- int ret = 0;
- struct termios *tsp;
-#if 0
- struct termio *tp;
-#endif
- struct iocblk *ip;
- char vstop, vstart;
- int ixon;
- int newflow;
-
- strbufc.maxlen = BUFSIZ;
- strbufc.buf = (char *)ctlbuf;
- strbufd.maxlen = bufsize-1;
- strbufd.len = 0;
- strbufd.buf = ibuf+1;
- ibuf[0] = 0;
-
- ret = getmsg(p, &strbufc, &strbufd, &flags);
- if (ret < 0) /* error of some sort -- probably EAGAIN */
- return(-1);
-
- if (strbufc.len <= 0 || ctlbuf[0] == M_DATA) {
- /* data message */
- if (strbufd.len > 0) { /* real data */
- return(strbufd.len + 1); /* count header char */
- } else {
- /* nothing there */
- errno = EAGAIN;
- return(-1);
- }
- }
-
- /*
- * It's a control message. Return 1, to look at the flag we set
- */
-
- switch (ctlbuf[0]) {
- case M_FLUSH:
- if (ibuf[1] & FLUSHW)
- ibuf[0] = TIOCPKT_FLUSHWRITE;
- return(1);
-
- case M_IOCTL:
- ip = (struct iocblk *) (ibuf+1);
-
- switch (ip->ioc_cmd) {
-#ifdef TCSETS
- case TCSETS:
- case TCSETSW:
- case TCSETSF:
- tsp = (struct termios *)
- (ibuf+1 + sizeof(struct iocblk));
- vstop = tsp->c_cc[VSTOP];
- vstart = tsp->c_cc[VSTART];
- ixon = tsp->c_iflag & IXON;
- break;
-#endif
-#if 0
- case TCSETA:
- case TCSETAW:
- case TCSETAF:
- tp = (struct termio *) (ibuf+1 + sizeof(struct iocblk));
- vstop = tp->c_cc[VSTOP];
- vstart = tp->c_cc[VSTART];
- ixon = tp->c_iflag & IXON;
- break;
-#endif
- default:
- errno = EAGAIN;
- return(-1);
- }
-
- newflow = (ixon && (vstart == 021) && (vstop == 023)) ? 1 : 0;
- if (newflow != flowison) { /* it's a change */
- flowison = newflow;
- ibuf[0] = newflow ? TIOCPKT_DOSTOP : TIOCPKT_NOSTOP;
- return(1);
- }
- }
-
- /* nothing worth doing anything about */
- errno = EAGAIN;
- return(-1);
-}
-#endif /* STREAMSPTY */
-
-/*
- * Send interrupt to process on other side of pty.
- * If it is in raw mode, just write NULL;
- * otherwise, write intr char.
- */
-void
-interrupt()
-{
- ptyflush(); /* half-hearted */
-
-#if defined(STREAMSPTY) && defined(TIOCSIGNAL)
- /* Streams PTY style ioctl to post a signal */
- if (really_stream)
- {
- int sig = SIGINT;
- ioctl(ourpty, TIOCSIGNAL, &sig);
- ioctl(ourpty, I_FLUSH, FLUSHR);
- }
-#else
-#ifdef TCSIG
- ioctl(ourpty, TCSIG, (char *)SIGINT);
-#else /* TCSIG */
- init_termbuf();
- *pfrontp++ = slctab[SLC_IP].sptr ?
- (unsigned char)*slctab[SLC_IP].sptr : '\177';
-#endif /* TCSIG */
-#endif
-}
-
-/*
- * Send quit to process on other side of pty.
- * If it is in raw mode, just write NULL;
- * otherwise, write quit char.
- */
-void
-sendbrk()
-{
- ptyflush(); /* half-hearted */
-#ifdef TCSIG
- ioctl(ourpty, TCSIG, (char *)SIGQUIT);
-#else /* TCSIG */
- init_termbuf();
- *pfrontp++ = slctab[SLC_ABORT].sptr ?
- (unsigned char)*slctab[SLC_ABORT].sptr : '\034';
-#endif /* TCSIG */
-}
-
-void
-sendsusp()
-{
-#ifdef SIGTSTP
- ptyflush(); /* half-hearted */
-# ifdef TCSIG
- ioctl(ourpty, TCSIG, (char *)SIGTSTP);
-# else /* TCSIG */
- *pfrontp++ = slctab[SLC_SUSP].sptr ?
- (unsigned char)*slctab[SLC_SUSP].sptr : '\032';
-# endif /* TCSIG */
-#endif /* SIGTSTP */
-}
-
-/*
- * When we get an AYT, if ^T is enabled, use that. Otherwise,
- * just send back "[Yes]".
- */
-void
-recv_ayt()
-{
-#if defined(SIGINFO) && defined(TCSIG)
- if (slctab[SLC_AYT].sptr && *slctab[SLC_AYT].sptr != _POSIX_VDISABLE) {
- ioctl(ourpty, TCSIG, (char *)SIGINFO);
- return;
- }
-#endif
- output_data("\r\n[Yes]\r\n");
-}
-
-void
-doeof()
-{
- init_termbuf();
-
- *pfrontp++ = slctab[SLC_EOF].sptr ?
- (unsigned char)*slctab[SLC_EOF].sptr : '\004';
-}
-
diff --git a/libexec/telnetd/telnetd.h b/libexec/telnetd/telnetd.h
deleted file mode 100644
index e0c40f22f26..00000000000
--- a/libexec/telnetd/telnetd.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * 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.
- *
- * @(#)telnetd.h 8.1 (Berkeley) 6/4/93
- */
-
-
-#include <err.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define HAVE_STDARG_H
-#define HAVE_NETDB_H
-#define HAVE_SYS_STAT_H
-#define HAVE_SYSLOG_H
-#define HAVE_UTMP_H
-#define HAVE_SYS_TYPES_H
-#define HAVE_SYS_SOCKET_H
-#define HAVE_FCNTL_H
-#define HAVE_SYS_IOCTL_H
-#define HAVE_UNISTD_H
-#define HAVE_SYS_UTSNAME_H
-#define HAVE_UNAME
-#define HAVE_UTIL_H
-#define HAVE_OPENPTY
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#include <time.h>
-#elif defined(HAVE_SYS_TIME_H)
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif /* HAVE_SYS_RESOURCE_H */
-
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_FILE_H
-#include <sys/file.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-/* including both <sys/ioctl.h> and <termios.h> in SunOS 4 generates a
- lot of warnings */
-
-#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_FILIO_H
-#include <sys/filio.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_NETINET_IN6_H
-#include <netinet/in6.h>
-#endif
-#ifdef HAVE_NETINET6_IN6_H
-#include <netinet6/in6.h>
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#include <signal.h>
-#include <errno.h>
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_SYSLOG_H
-#include <syslog.h>
-#endif
-#include <ctype.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <termios.h>
-
-#ifdef HAVE_PTY_H
-#include <pty.h>
-#endif
-
-#include "defs.h"
-
-#ifndef _POSIX_VDISABLE
-# ifdef VDISABLE
-# define _POSIX_VDISABLE VDISABLE
-# else
-# define _POSIX_VDISABLE ((unsigned char)'\377')
-# endif
-#endif
-
-
-#ifdef HAVE_SYS_PTY_H
-#include <sys/pty.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#ifdef HAVE_SYS_PTYIO_H
-#include <sys/ptyio.h>
-#endif
-
-#ifdef HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif
-
-#ifdef HAVE_ARPA_TELNET_H
-#include <arpa/telnet.h>
-#endif
-
-#ifdef HAVE_STDARG_H
-#include <stdarg.h>
-#endif
-
-#include "ext.h"
-
-#ifdef SOCKS
-#include <socks.h>
-/* This doesn't belong here. */
-struct tm *localtime(const time_t *);
-struct hostent *gethostbyname(const char *);
-#endif
-
-#ifdef KRB4
-#include <kerberosIV/krb.h>
-#endif
-
-#ifdef AUTHENTICATION
-#include <auth.h>
-#include <misc.h>
-#ifdef ENCRYPTION
-#include <encrypt.h>
-#endif
-#endif
-
-#ifdef HAVE_LIBUTIL_H
-#include <libutil.h>
-#endif
-
-
-/* Don't use the system login, use our version instead */
-
-/* BINDIR should be defined somewhere else... */
-
-#ifndef BINDIR
-#define BINDIR "/usr/bin"
-#endif
-
-#undef _PATH_LOGIN
-#define _PATH_LOGIN BINDIR "/login"
-
-/* fallbacks */
-
-#ifndef _PATH_DEV
-#define _PATH_DEV "/dev/"
-#endif
-
-#ifndef _PATH_TTY
-#define _PATH_TTY "/dev/tty"
-#endif /* _PATH_TTY */
-
-#ifdef DIAGNOSTICS
-#define DIAG(a,b) if (diagnostic & (a)) b
-#else
-#define DIAG(a,b)
-#endif
-
-/* other external variables */
-extern char **environ;
-
-/* prototypes */
-
-/* appends data to nfrontp and advances */
-int output_data (const char *format, ...)
-#ifdef __GNUC__
-__attribute__ ((format (printf, 1, 2)))
-#endif
-;
-
-void esetenv(const char *, const char *, int);
-void mini_inetd(int);
-void socket_set_reuseaddr (int, int);
-
diff --git a/libexec/telnetd/termstat.c b/libexec/telnetd/termstat.c
deleted file mode 100644
index e2e3edaff38..00000000000
--- a/libexec/telnetd/termstat.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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 "telnetd.h"
-
-/* RCSID("$KTH: termstat.c,v 1.11 1997/05/11 06:30:04 assar Exp $") */
-
-/*
- * local variables
- */
-int def_tspeed = -1, def_rspeed = -1;
-#ifdef TIOCSWINSZ
-int def_row = 0, def_col = 0;
-#endif
-
-/*
- * flowstat
- *
- * Check for changes to flow control
- */
-void
-flowstat()
-{
- if (his_state_is_will(TELOPT_LFLOW)) {
- if (tty_flowmode() != flowmode) {
- flowmode = tty_flowmode();
- 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();
- 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)
-{
- void netflush(void);
-
- /*
- * Get a copy of terminal characteristics.
- */
- init_termbuf();
-
- /*
- * Process request from client. code tells what it is.
- */
- switch (code) {
- case TELOPT_NAWS:
-#ifdef TIOCSWINSZ
- {
- struct winsize ws;
-
- def_col = parm1;
- def_row = parm2;
-
- /*
- * Change window size as requested by client.
- */
-
- ws.ws_col = parm1;
- ws.ws_row = parm2;
- ioctl(ourpty, TIOCSWINSZ, (char *)&ws);
- }
-#endif /* TIOCSWINSZ */
-
- break;
-
- case TELOPT_TSPEED:
- {
- def_tspeed = parm1;
- def_rspeed = parm2;
- /*
- * 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();
-
-}
diff --git a/libexec/telnetd/utility.c b/libexec/telnetd/utility.c
deleted file mode 100644
index f0a7202c590..00000000000
--- a/libexec/telnetd/utility.c
+++ /dev/null
@@ -1,1169 +0,0 @@
-/*
- * 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.
- */
-
-#define PRINTOPTIONS
-#include "telnetd.h"
-
-/* RCSID("$KTH: utility.c,v 1.25 2001/05/17 00:34:42 assar Exp $"); */
-
-/*
- * utility functions performing io related tasks
- */
-
-/*
- * ttloop
- *
- * A small subroutine to flush the network output buffer, get some
- * data from the network, and pass it through the telnet state
- * machine. We also flush the pty input buffer (by dropping its data)
- * if it becomes too full.
- *
- * return 0 if OK or 1 if interrupted by a signal.
- */
-
-int
-ttloop(void)
-{
- void netflush(void);
-
- DIAG(TD_REPORT, {
- output_data("td: ttloop\r\n");
- });
- if (nfrontp-nbackp)
- netflush();
- ncc = read(net, netibuf, sizeof netibuf);
- if (ncc < 0) {
- if (errno == EINTR)
- return 1;
- syslog(LOG_INFO, "ttloop: read: %m");
- exit(1);
- } else if (ncc == 0) {
- syslog(LOG_INFO, "ttloop: peer died");
- exit(1);
- }
- DIAG(TD_REPORT, {
- output_data("td: ttloop read %d chars\r\n", ncc);
- });
- netip = netibuf;
- telrcv(); /* state machine */
- if (ncc > 0) {
- pfrontp = pbackp = ptyobuf;
- telrcv();
- }
- return 0;
-} /* end of ttloop */
-
-/*
- * Check a descriptor to see if out of band data exists on it.
- */
-int
-stilloob(int s)
-{
- static struct timeval timeout = { 0 };
- fd_set excepts;
- int value;
-
- if (s >= FD_SETSIZE)
- fatal(ourpty, "fd too large");
-
- do {
- FD_ZERO(&excepts);
- FD_SET(s, &excepts);
- value = select(s+1, 0, 0, &excepts, &timeout);
- } while ((value == -1) && (errno == EINTR));
-
- if (value < 0) {
- fatalperror(ourpty, "select");
- }
- if (FD_ISSET(s, &excepts)) {
- return 1;
- } else {
- return 0;
- }
-}
-
-void
-ptyflush(void)
-{
- int n;
-
- if ((n = pfrontp - pbackp) > 0) {
- DIAG((TD_REPORT | TD_PTYDATA), {
- output_data("td: ptyflush %d chars\r\n", n);
- });
- DIAG(TD_PTYDATA, printdata("pd", pbackp, n));
- n = write(ourpty, pbackp, n);
- }
- if (n < 0) {
- if (errno == EWOULDBLOCK || errno == EINTR)
- return;
- cleanup(0);
- }
- pbackp += n;
- if (pbackp == pfrontp)
- pbackp = pfrontp = ptyobuf;
-}
-
-/*
- * nextitem()
- *
- * Return the address of the next "item" in the TELNET data
- * stream. This will be the address of the next character if
- * the current address is a user data character, or it will
- * be the address of the character following the TELNET command
- * if the current address is a TELNET IAC ("I Am a Command")
- * character.
- */
-char *
-nextitem(char *current)
-{
- if ((*current&0xff) != IAC) {
- return current+1;
- }
- switch (*(current+1)&0xff) {
- case DO:
- case DONT:
- case WILL:
- case WONT:
- return current+3;
- case SB:{
- /* loop forever looking for the SE */
- char *look = current+2;
-
- for (;;) {
- if ((*look++&0xff) == IAC) {
- if ((*look++&0xff) == SE) {
- return look;
- }
- }
- }
- }
- default:
- return current+2;
- }
-}
-
-
-/*
- * netclear()
- *
- * We are about to do a TELNET SYNCH operation. Clear
- * the path to the network.
- *
- * Things are a bit tricky since we may have sent the first
- * byte or so of a previous TELNET command into the network.
- * So, we have to scan the network buffer from the beginning
- * until we are up to where we want to be.
- *
- * A side effect of what we do, just to keep things
- * simple, is to clear the urgent data pointer. The principal
- * caller should be setting the urgent data pointer AFTER calling
- * us in any case.
- */
-void
-netclear(void)
-{
- char *thisitem, *next;
- char *good;
-#define wewant(p) ((nfrontp > p) && ((*p&0xff) == IAC) && \
- ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
-
-#ifdef ENCRYPTION
- thisitem = nclearto > netobuf ? nclearto : netobuf;
-#else
- thisitem = netobuf;
-#endif
-
- while ((next = nextitem(thisitem)) <= nbackp) {
- thisitem = next;
- }
-
- /* Now, thisitem is first before/at boundary. */
-
-#ifdef ENCRYPTION
- good = nclearto > netobuf ? nclearto : netobuf;
-#else
- good = netobuf; /* where the good bytes go */
-#endif
-
- while (nfrontp > thisitem) {
- if (wewant(thisitem)) {
- int length;
-
- next = thisitem;
- do {
- next = nextitem(next);
- } while (wewant(next) && (nfrontp > next));
- length = next-thisitem;
- memmove(good, thisitem, length);
- good += length;
- thisitem = next;
- } else {
- thisitem = nextitem(thisitem);
- }
- }
-
- nbackp = netobuf;
- nfrontp = good; /* next byte to be sent */
- neturg = 0;
-} /* end of netclear */
-
-/*
- * netflush
- * Send as much data as possible to the network,
- * handling requests for urgent data.
- */
-void
-netflush(void)
-{
- int n;
- extern int not42;
-
- if ((n = nfrontp - nbackp) > 0) {
- DIAG(TD_REPORT,
- { n += output_data("td: netflush %d chars\r\n", n);
- });
-#ifdef ENCRYPTION
- if (encrypt_output) {
- char *s = nclearto ? nclearto : nbackp;
- if (nfrontp - s > 0) {
- (*encrypt_output)((unsigned char *)s, nfrontp-s);
- nclearto = nfrontp;
- }
- }
-#endif
- /*
- * if no urgent data, or if the other side appears to be an
- * old 4.2 client (and thus unable to survive TCP urgent data),
- * write the entire buffer in non-OOB mode.
- */
-#if 1 /* remove this to make it work between solaris 2.6 and linux */
- if ((neturg == 0) || (not42 == 0)) {
-#endif
- n = write(net, nbackp, n); /* normal write */
-#if 1 /* remove this to make it work between solaris 2.6 and linux */
- } else {
- n = neturg - nbackp;
- /*
- * In 4.2 (and 4.3) systems, there is some question about
- * what byte in a sendOOB operation is the "OOB" data.
- * To make ourselves compatible, we only send ONE byte
- * out of band, the one WE THINK should be OOB (though
- * we really have more the TCP philosophy of urgent data
- * rather than the Unix philosophy of OOB data).
- */
- if (n > 1) {
- n = send(net, nbackp, n-1, 0); /* send URGENT all by itself */
- } else {
- n = send(net, nbackp, n, MSG_OOB); /* URGENT data */
- }
- }
-#endif
- }
- if (n < 0) {
- if (errno == EWOULDBLOCK || errno == EINTR)
- return;
- cleanup(0);
- }
- nbackp += n;
-#ifdef ENCRYPTION
- if (nbackp > nclearto)
- nclearto = 0;
-#endif
- if (nbackp >= neturg) {
- neturg = 0;
- }
- if (nbackp == nfrontp) {
- nbackp = nfrontp = netobuf;
-#ifdef ENCRYPTION
- nclearto = 0;
-#endif
- }
- return;
-}
-
-
-/*
- * writenet
- *
- * Just a handy little function to write a bit of raw data to the net.
- * It will force a transmit of the buffer if necessary
- *
- * arguments
- * ptr - A pointer to a character string to write
- * len - How many bytes to write
- */
-void
-writenet(unsigned char *ptr, int len)
-{
- /* flush buffer if no room for new data) */
- while ((&netobuf[BUFSIZ] - nfrontp) < len) {
- /* if this fails, don't worry, buffer is a little big */
- netflush();
- }
-
- memmove(nfrontp, ptr, len);
- nfrontp += len;
-}
-
-
-/*
- * miscellaneous functions doing a variety of little jobs follow ...
- */
-
-
-void fatal(int f, char *msg)
-{
- char buf[BUFSIZ];
-
- snprintf(buf, sizeof(buf), "telnetd: %s.\r\n", msg);
-#ifdef ENCRYPTION
- if (encrypt_output) {
- /*
- * Better turn off encryption first....
- * Hope it flushes...
- */
- encrypt_send_end();
- netflush();
- }
-#endif
- write(f, buf, (int)strlen(buf));
- sleep(1); /*XXX*/
- exit(1);
-}
-
-void
-fatalperror_errno(int f, const char *msg, int error)
-{
- char buf[BUFSIZ];
-
- snprintf(buf, sizeof(buf), "%s: %s", msg, strerror(error));
- fatal(f, buf);
-}
-
-void
-fatalperror(int f, const char *msg)
-{
- fatalperror_errno(f, msg, errno);
-}
-
-char editedhost[32];
-
-void edithost(char *pat, char *host)
-{
- char *res = editedhost;
-
- if (!pat)
- pat = "";
- while (*pat) {
- switch (*pat) {
-
- case '#':
- if (*host)
- host++;
- break;
-
- case '@':
- if (*host)
- *res++ = *host++;
- break;
-
- default:
- *res++ = *pat;
- break;
- }
- if (res == &editedhost[sizeof editedhost - 1]) {
- *res = '\0';
- return;
- }
- pat++;
- }
- if (*host)
- strlcpy (res, host,
- sizeof editedhost - (res - editedhost));
- else
- *res = '\0';
- editedhost[sizeof editedhost - 1] = '\0';
-}
-
-static char *putlocation;
-
-void
-putstr(char *s)
-{
-
- while (*s)
- putchr(*s++);
-}
-
-void
-putchr(int cc)
-{
- *putlocation++ = cc;
-}
-
-/*
- * This is split on two lines so that SCCS will not see the M
- * between two % signs and expand it...
- */
-static char fmtstr[] = { "%l:%M" "%P on %A, %d %B %Y" };
-
-void putf(char *cp, char *where)
-{
-#ifdef HAVE_UNAME
- struct utsname name;
-#endif
- char *slash;
- time_t t;
- char db[100];
-
- /* if we don't have uname, set these to sensible values */
- char *sysname = "Unix",
- *machine = "",
- *release = "",
- *version = "";
-
-#ifdef HAVE_UNAME
- uname(&name);
- sysname=name.sysname;
- machine=name.machine;
- release=name.release;
- version=name.version;
-#endif
-
- putlocation = where;
-
- while (*cp) {
- if (*cp != '%') {
- putchr(*cp++);
- continue;
- }
- switch (*++cp) {
-
- case 't':
-#ifdef STREAMSPTY
- /* names are like /dev/pts/2 -- we want pts/2 */
- slash = strchr(line+1, '/');
-#else
- slash = strrchr(line, '/');
-#endif
- if (slash == (char *) 0)
- putstr(line);
- else
- putstr(&slash[1]);
- break;
-
- case 'h':
- putstr(editedhost);
- break;
-
- case 's':
- putstr(sysname);
- break;
-
- case 'm':
- putstr(machine);
- break;
-
- case 'r':
- putstr(release);
- break;
-
- case 'v':
- putstr(version);
- break;
-
- case 'd':
- time(&t);
- strftime(db, sizeof(db), fmtstr, localtime(&t));
- putstr(db);
- break;
-
- case '%':
- putchr('%');
- break;
- }
- cp++;
- }
-}
-
-#ifdef DIAGNOSTICS
-/*
- * Print telnet options and commands in plain text, if possible.
- */
-void
-printoption(char *fmt, int option)
-{
- if (TELOPT_OK(option))
- output_data("%s %s\r\n",
- fmt,
- TELOPT(option));
- else if (TELCMD_OK(option))
- output_data("%s %s\r\n",
- fmt,
- TELCMD(option));
- else
- output_data("%s %d\r\n",
- fmt,
- option);
- return;
-}
-
-void
-printsub(int direction, unsigned char *pointer, int length)
- /* '<' or '>' */
- /* where suboption data sits */
- /* length of suboption data */
-{
- int i = 0;
-#ifdef AUTHENTICATION
- unsigned char buf[512];
-#endif
-
- if (!(diagnostic & TD_OPTIONS))
- return;
-
- if (direction) {
- output_data("td: %s suboption ",
- direction == '<' ? "recv" : "send");
- if (length >= 3) {
- int j;
-
- i = pointer[length-2];
- j = pointer[length-1];
-
- if (i != IAC || j != SE) {
- output_data("(terminated by ");
- if (TELOPT_OK(i))
- output_data("%s ",
- TELOPT(i));
- else if (TELCMD_OK(i))
- output_data("%s ",
- TELCMD(i));
- else
- output_data("%d ",
- i);
- if (TELOPT_OK(j))
- output_data("%s",
- TELOPT(j));
- else if (TELCMD_OK(j))
- output_data("%s",
- TELCMD(j));
- else
- output_data("%d",
- j);
- output_data(", not IAC SE!) ");
- }
- }
- length -= 2;
- }
- if (length < 1) {
- output_data("(Empty suboption??\?)");
- return;
- }
- switch (pointer[0]) {
- case TELOPT_TTYPE:
- output_data("TERMINAL-TYPE ");
- switch (pointer[1]) {
- case TELQUAL_IS:
- output_data("IS \"%.*s\"",
- length-2,
- (char *)pointer+2);
- break;
- case TELQUAL_SEND:
- output_data("SEND");
- break;
- default:
- output_data("- unknown qualifier %d (0x%x).",
- pointer[1], pointer[1]);
- }
- break;
- case TELOPT_TSPEED:
- output_data("TERMINAL-SPEED");
- if (length < 2) {
- output_data(" (empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case TELQUAL_IS:
- output_data(" IS %.*s", length-2, (char *)pointer+2);
- break;
- default:
- if (pointer[1] == 1)
- output_data(" SEND");
- else
- output_data(" %d (unknown)", pointer[1]);
- for (i = 2; i < length; i++) {
- output_data(" ?%d?", pointer[i]);
- }
- break;
- }
- break;
-
- case TELOPT_LFLOW:
- output_data("TOGGLE-FLOW-CONTROL");
- if (length < 2) {
- output_data(" (empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case LFLOW_OFF:
- output_data(" OFF");
- break;
- case LFLOW_ON:
- output_data(" ON");
- break;
- case LFLOW_RESTART_ANY:
- output_data(" RESTART-ANY");
- break;
- case LFLOW_RESTART_XON:
- output_data(" RESTART-XON");
- break;
- default:
- output_data(" %d (unknown)",
- pointer[1]);
- }
- for (i = 2; i < length; i++) {
- output_data(" ?%d?",
- pointer[i]);
- }
- break;
-
- case TELOPT_NAWS:
- output_data("NAWS");
- if (length < 2) {
- output_data(" (empty suboption??\?)");
- break;
- }
- if (length == 2) {
- output_data(" ?%d?",
- pointer[1]);
- break;
- }
- output_data(" %u %u(%u)",
- pointer[1],
- pointer[2],
- (((unsigned int)pointer[1])<<8) + pointer[2]);
- if (length == 4) {
- output_data(" ?%d?",
- pointer[3]);
- break;
- }
- output_data(" %u %u(%u)",
- pointer[3],
- pointer[4],
- (((unsigned int)pointer[3])<<8) + pointer[4]);
- for (i = 5; i < length; i++) {
- output_data(" ?%d?",
- pointer[i]);
- }
- break;
-
- case TELOPT_LINEMODE:
- output_data("LINEMODE ");
- if (length < 2) {
- output_data(" (empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case WILL:
- output_data("WILL ");
- goto common;
- case WONT:
- output_data("WONT ");
- goto common;
- case DO:
- output_data("DO ");
- goto common;
- case DONT:
- output_data("DONT ");
- common:
- if (length < 3) {
- output_data("(no option??\?)");
- break;
- }
- switch (pointer[2]) {
- case LM_FORWARDMASK:
- output_data("Forward Mask");
- for (i = 3; i < length; i++) {
- output_data(" %x", pointer[i]);
- }
- break;
- default:
- output_data("%d (unknown)",
- pointer[2]);
- for (i = 3; i < length; i++) {
- output_data(" %d",
- pointer[i]);
- }
- break;
- }
- break;
-
- case LM_SLC:
- output_data("SLC");
- for (i = 2; i < length - 2; i += 3) {
- if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
- output_data(" %s",
- SLC_NAME(pointer[i+SLC_FUNC]));
- else
- output_data(" %d",
- pointer[i+SLC_FUNC]);
- switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
- case SLC_NOSUPPORT:
- output_data(" NOSUPPORT");
- break;
- case SLC_CANTCHANGE:
- output_data(" CANTCHANGE");
- break;
- case SLC_VARIABLE:
- output_data(" VARIABLE");
- break;
- case SLC_DEFAULT:
- output_data(" DEFAULT");
- break;
- }
- output_data("%s%s%s",
- pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
- pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
- pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
- if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
- SLC_FLUSHOUT| SLC_LEVELBITS)) {
- output_data("(0x%x)",
- pointer[i+SLC_FLAGS]);
- }
- output_data(" %d;",
- pointer[i+SLC_VALUE]);
- if ((pointer[i+SLC_VALUE] == IAC) &&
- (pointer[i+SLC_VALUE+1] == IAC))
- i++;
- }
- for (; i < length; i++) {
- output_data(" ?%d?",
- pointer[i]);
- }
- break;
-
- case LM_MODE:
- output_data("MODE ");
- if (length < 3) {
- output_data("(no mode??\?)");
- break;
- }
- {
- char tbuf[32];
- snprintf(tbuf,
- sizeof(tbuf),
- "%s%s%s%s%s",
- pointer[2]&MODE_EDIT ? "|EDIT" : "",
- pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
- pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
- pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
- pointer[2]&MODE_ACK ? "|ACK" : "");
- output_data("%s",
- tbuf[1] ? &tbuf[1] : "0");
- }
- if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) {
- output_data(" (0x%x)",
- pointer[2]);
- }
- for (i = 3; i < length; i++) {
- output_data(" ?0x%x?",
- pointer[i]);
- }
- break;
- default:
- output_data("%d (unknown)",
- pointer[1]);
- for (i = 2; i < length; i++) {
- output_data(" %d", pointer[i]);
- }
- }
- break;
-
- case TELOPT_STATUS: {
- char *cp;
- int j, k;
-
- output_data("STATUS");
-
- switch (pointer[1]) {
- default:
- if (pointer[1] == TELQUAL_SEND)
- output_data(" SEND");
- else
- output_data(" %d (unknown)",
- pointer[1]);
- for (i = 2; i < length; i++) {
- output_data(" ?%d?",
- pointer[i]);
- }
- break;
- case TELQUAL_IS:
- output_data(" IS\r\n");
-
- for (i = 2; i < length; i++) {
- switch(pointer[i]) {
- case DO: cp = "DO"; goto common2;
- case DONT: cp = "DONT"; goto common2;
- case WILL: cp = "WILL"; goto common2;
- case WONT: cp = "WONT"; goto common2;
- common2:
- i++;
- if (TELOPT_OK(pointer[i]))
- output_data(" %s %s",
- cp,
- TELOPT(pointer[i]));
- else
- output_data(" %s %d",
- cp,
- pointer[i]);
-
- output_data("\r\n");
- break;
-
- case SB:
- output_data(" SB ");
- i++;
- j = k = i;
- while (j < length) {
- if (pointer[j] == SE) {
- if (j+1 == length)
- break;
- if (pointer[j+1] == SE)
- j++;
- else
- break;
- }
- pointer[k++] = pointer[j++];
- }
- printsub(0, &pointer[i], k - i);
- if (i < length) {
- output_data(" SE");
- i = j;
- } else
- i = j - 1;
-
- output_data("\r\n");
-
- break;
-
- default:
- output_data(" %d",
- pointer[i]);
- break;
- }
- }
- break;
- }
- break;
- }
-
- case TELOPT_XDISPLOC:
- output_data("X-DISPLAY-LOCATION ");
- switch (pointer[1]) {
- case TELQUAL_IS:
- output_data("IS \"%.*s\"",
- length-2,
- (char *)pointer+2);
- break;
- case TELQUAL_SEND:
- output_data("SEND");
- break;
- default:
- output_data("- unknown qualifier %d (0x%x).",
- pointer[1], pointer[1]);
- }
- break;
-
- case TELOPT_NEW_ENVIRON:
- output_data("NEW-ENVIRON ");
- goto env_common1;
- case TELOPT_OLD_ENVIRON:
- output_data("OLD-ENVIRON");
- env_common1:
- switch (pointer[1]) {
- case TELQUAL_IS:
- output_data("IS ");
- goto env_common;
- case TELQUAL_SEND:
- output_data("SEND ");
- goto env_common;
- case TELQUAL_INFO:
- output_data("INFO ");
- env_common:
- {
- int noquote = 2;
- for (i = 2; i < length; i++ ) {
- switch (pointer[i]) {
- case NEW_ENV_VAR:
- output_data("\" VAR " + noquote);
- noquote = 2;
- break;
-
- case NEW_ENV_VALUE:
- output_data("\" VALUE " + noquote);
- noquote = 2;
- break;
-
- case ENV_ESC:
- output_data("\" ESC " + noquote);
- noquote = 2;
- break;
-
- case ENV_USERVAR:
- output_data("\" USERVAR " + noquote);
- noquote = 2;
- break;
-
- default:
- if (isprint(pointer[i]) && pointer[i] != '"') {
- if (noquote) {
- output_data ("\"");
- noquote = 0;
- }
- output_data ("%c", pointer[i]);
- } else {
- output_data("\" %03o " + noquote,
- pointer[i]);
- noquote = 2;
- }
- break;
- }
- }
- if (!noquote)
- output_data ("\"");
- break;
- }
- }
- break;
-
-#ifdef AUTHENTICATION
- case TELOPT_AUTHENTICATION:
- output_data("AUTHENTICATION");
-
- if (length < 2) {
- output_data(" (empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case TELQUAL_REPLY:
- case TELQUAL_IS:
- output_data(" %s ",
- (pointer[1] == TELQUAL_IS) ?
- "IS" : "REPLY");
- if (AUTHTYPE_NAME_OK(pointer[2]))
- output_data("%s ",
- AUTHTYPE_NAME(pointer[2]));
- else
- output_data("%d ",
- pointer[2]);
- if (length < 3) {
- output_data("(partial suboption??\?)");
- break;
- }
- output_data("%s|%s",
- ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
- "CLIENT" : "SERVER",
- ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
- "MUTUAL" : "ONE-WAY");
-
- auth_printsub(&pointer[1], length - 1, buf, sizeof(buf));
- output_data("%s",
- buf);
- break;
-
- case TELQUAL_SEND:
- i = 2;
- output_data(" SEND ");
- while (i < length) {
- if (AUTHTYPE_NAME_OK(pointer[i]))
- output_data("%s ",
- AUTHTYPE_NAME(pointer[i]));
- else
- output_data("%d ",
- pointer[i]);
- if (++i >= length) {
- output_data("(partial suboption??\?)");
- break;
- }
- output_data("%s|%s ",
- ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
- "CLIENT" : "SERVER",
- ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
- "MUTUAL" : "ONE-WAY");
- ++i;
- }
- break;
-
- case TELQUAL_NAME:
- i = 2;
- output_data(" NAME \"%.*s\"",
- length - 2,
- pointer);
- break;
-
- default:
- for (i = 2; i < length; i++) {
- output_data(" ?%d?",
- pointer[i]);
- }
- break;
- }
- break;
-#endif
-
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- output_data("ENCRYPT");
- if (length < 2) {
- output_data(" (empty suboption?)");
- break;
- }
- switch (pointer[1]) {
- case ENCRYPT_START:
- output_data(" START");
- break;
-
- case ENCRYPT_END:
- output_data(" END");
- break;
-
- case ENCRYPT_REQSTART:
- output_data(" REQUEST-START");
- break;
-
- case ENCRYPT_REQEND:
- output_data(" REQUEST-END");
- break;
-
- case ENCRYPT_IS:
- case ENCRYPT_REPLY:
- output_data(" %s ",
- (pointer[1] == ENCRYPT_IS) ?
- "IS" : "REPLY");
- if (length < 3) {
- output_data(" (partial suboption?)");
- break;
- }
- if (ENCTYPE_NAME_OK(pointer[2]))
- output_data("%s ",
- ENCTYPE_NAME(pointer[2]));
- else
- output_data(" %d (unknown)",
- pointer[2]);
-
- encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf));
- output_data("%s",
- buf);
- break;
-
- case ENCRYPT_SUPPORT:
- i = 2;
- output_data(" SUPPORT ");
- while (i < length) {
- if (ENCTYPE_NAME_OK(pointer[i]))
- output_data("%s ",
- ENCTYPE_NAME(pointer[i]));
- else
- output_data("%d ",
- pointer[i]);
- i++;
- }
- break;
-
- case ENCRYPT_ENC_KEYID:
- output_data(" ENC_KEYID %d", pointer[1]);
- goto encommon;
-
- case ENCRYPT_DEC_KEYID:
- output_data(" DEC_KEYID %d", pointer[1]);
- goto encommon;
-
- default:
- output_data(" %d (unknown)", pointer[1]);
- encommon:
- for (i = 2; i < length; i++) {
- output_data(" %d", pointer[i]);
- }
- break;
- }
- break;
-#endif
-
- default:
- if (TELOPT_OK(pointer[0]))
- output_data("%s (unknown)",
- TELOPT(pointer[0]));
- else
- output_data("%d (unknown)",
- pointer[i]);
- for (i = 1; i < length; i++) {
- output_data(" %d", pointer[i]);
- }
- break;
- }
- output_data("\r\n");
-}
-
-/*
- * Dump a data buffer in hex and ascii to the output data stream.
- */
-void
-printdata(char *tag, char *ptr, int cnt)
-{
- int i;
- char xbuf[30];
-
- while (cnt) {
- /* flush net output buffer if no room for new data) */
- if ((&netobuf[BUFSIZ] - nfrontp) < 80) {
- netflush();
- }
-
- /* add a line of output */
- output_data("%s: ", tag);
- for (i = 0; i < 20 && cnt; i++) {
- output_data("%02x", *ptr);
- if (isprint(*ptr)) {
- xbuf[i] = *ptr;
- } else {
- xbuf[i] = '.';
- }
- if (i % 2) {
- output_data(" ");
- }
- cnt--;
- ptr++;
- }
- xbuf[i] = '\0';
- output_data(" %s\r\n", xbuf);
- }
-}
-#endif /* DIAGNOSTICS */