Initial import of BSD telnet. This will be used to build the kerberised
telnet, and after userland diffs have been merged in, will be used to build the non-kerberised sources as well. (See unifdef(1) for details)
This commit is contained in:
commit
a9e6ba3f81
320
contrib/telnet/arpa/telnet.h
Normal file
320
contrib/telnet/arpa/telnet.h
Normal file
@ -0,0 +1,320 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)telnet.h 8.2 (Berkeley) 12/15/93
|
||||
*/
|
||||
|
||||
#ifndef _TELNET_H_
|
||||
#define _TELNET_H_
|
||||
|
||||
/*
|
||||
* Definitions for the TELNET protocol.
|
||||
*/
|
||||
#define IAC 255 /* interpret as command: */
|
||||
#define DONT 254 /* you are not to use option */
|
||||
#define DO 253 /* please, you use option */
|
||||
#define WONT 252 /* I won't use option */
|
||||
#define WILL 251 /* I will use option */
|
||||
#define SB 250 /* interpret as subnegotiation */
|
||||
#define GA 249 /* you may reverse the line */
|
||||
#define EL 248 /* erase the current line */
|
||||
#define EC 247 /* erase the current character */
|
||||
#define AYT 246 /* are you there */
|
||||
#define AO 245 /* abort output--but let prog finish */
|
||||
#define IP 244 /* interrupt process--permanently */
|
||||
#define BREAK 243 /* break */
|
||||
#define DM 242 /* data mark--for connect. cleaning */
|
||||
#define NOP 241 /* nop */
|
||||
#define SE 240 /* end sub negotiation */
|
||||
#define EOR 239 /* end of record (transparent mode) */
|
||||
#define ABORT 238 /* Abort process */
|
||||
#define SUSP 237 /* Suspend process */
|
||||
#define xEOF 236 /* End of file: EOF is already used... */
|
||||
|
||||
#define SYNCH 242 /* for telfunc calls */
|
||||
|
||||
#ifdef TELCMDS
|
||||
char *telcmds[] = {
|
||||
"EOF", "SUSP", "ABORT", "EOR",
|
||||
"SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
|
||||
"EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
|
||||
};
|
||||
#else
|
||||
extern char *telcmds[];
|
||||
#endif
|
||||
|
||||
#define TELCMD_FIRST xEOF
|
||||
#define TELCMD_LAST IAC
|
||||
#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \
|
||||
(unsigned int)(x) >= TELCMD_FIRST)
|
||||
#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
|
||||
|
||||
/* telnet options */
|
||||
#define TELOPT_BINARY 0 /* 8-bit data path */
|
||||
#define TELOPT_ECHO 1 /* echo */
|
||||
#define TELOPT_RCP 2 /* prepare to reconnect */
|
||||
#define TELOPT_SGA 3 /* suppress go ahead */
|
||||
#define TELOPT_NAMS 4 /* approximate message size */
|
||||
#define TELOPT_STATUS 5 /* give status */
|
||||
#define TELOPT_TM 6 /* timing mark */
|
||||
#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
|
||||
#define TELOPT_NAOL 8 /* negotiate about output line width */
|
||||
#define TELOPT_NAOP 9 /* negotiate about output page size */
|
||||
#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
|
||||
#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
|
||||
#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
|
||||
#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
|
||||
#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
|
||||
#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
|
||||
#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
|
||||
#define TELOPT_XASCII 17 /* extended ascic character set */
|
||||
#define TELOPT_LOGOUT 18 /* force logout */
|
||||
#define TELOPT_BM 19 /* byte macro */
|
||||
#define TELOPT_DET 20 /* data entry terminal */
|
||||
#define TELOPT_SUPDUP 21 /* supdup protocol */
|
||||
#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
|
||||
#define TELOPT_SNDLOC 23 /* send location */
|
||||
#define TELOPT_TTYPE 24 /* terminal type */
|
||||
#define TELOPT_EOR 25 /* end or record */
|
||||
#define TELOPT_TUID 26 /* TACACS user identification */
|
||||
#define TELOPT_OUTMRK 27 /* output marking */
|
||||
#define TELOPT_TTYLOC 28 /* terminal location number */
|
||||
#define TELOPT_3270REGIME 29 /* 3270 regime */
|
||||
#define TELOPT_X3PAD 30 /* X.3 PAD */
|
||||
#define TELOPT_NAWS 31 /* window size */
|
||||
#define TELOPT_TSPEED 32 /* terminal speed */
|
||||
#define TELOPT_LFLOW 33 /* remote flow control */
|
||||
#define TELOPT_LINEMODE 34 /* Linemode option */
|
||||
#define TELOPT_XDISPLOC 35 /* X Display Location */
|
||||
#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */
|
||||
#define TELOPT_AUTHENTICATION 37/* Authenticate */
|
||||
#define TELOPT_ENCRYPT 38 /* Encryption option */
|
||||
#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
|
||||
#define TELOPT_EXOPL 255 /* extended-options-list */
|
||||
|
||||
|
||||
#define NTELOPTS (1+TELOPT_NEW_ENVIRON)
|
||||
#ifdef TELOPTS
|
||||
char *telopts[NTELOPTS+1] = {
|
||||
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
|
||||
"STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
|
||||
"NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
|
||||
"NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
|
||||
"DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
|
||||
"SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
|
||||
"TACACS UID", "OUTPUT MARKING", "TTYLOC",
|
||||
"3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
|
||||
"LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
|
||||
"ENCRYPT", "NEW-ENVIRON",
|
||||
0,
|
||||
};
|
||||
#define TELOPT_FIRST TELOPT_BINARY
|
||||
#define TELOPT_LAST TELOPT_NEW_ENVIRON
|
||||
#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
|
||||
#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
|
||||
#endif
|
||||
|
||||
/* sub-option qualifiers */
|
||||
#define TELQUAL_IS 0 /* option is... */
|
||||
#define TELQUAL_SEND 1 /* send option */
|
||||
#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
|
||||
#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
|
||||
#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
|
||||
|
||||
#define LFLOW_OFF 0 /* Disable remote flow control */
|
||||
#define LFLOW_ON 1 /* Enable remote flow control */
|
||||
#define LFLOW_RESTART_ANY 2 /* Restart output on any char */
|
||||
#define LFLOW_RESTART_XON 3 /* Restart output only on XON */
|
||||
|
||||
/*
|
||||
* LINEMODE suboptions
|
||||
*/
|
||||
|
||||
#define LM_MODE 1
|
||||
#define LM_FORWARDMASK 2
|
||||
#define LM_SLC 3
|
||||
|
||||
#define MODE_EDIT 0x01
|
||||
#define MODE_TRAPSIG 0x02
|
||||
#define MODE_ACK 0x04
|
||||
#define MODE_SOFT_TAB 0x08
|
||||
#define MODE_LIT_ECHO 0x10
|
||||
|
||||
#define MODE_MASK 0x1f
|
||||
|
||||
/* Not part of protocol, but needed to simplify things... */
|
||||
#define MODE_FLOW 0x0100
|
||||
#define MODE_ECHO 0x0200
|
||||
#define MODE_INBIN 0x0400
|
||||
#define MODE_OUTBIN 0x0800
|
||||
#define MODE_FORCE 0x1000
|
||||
|
||||
#define SLC_SYNCH 1
|
||||
#define SLC_BRK 2
|
||||
#define SLC_IP 3
|
||||
#define SLC_AO 4
|
||||
#define SLC_AYT 5
|
||||
#define SLC_EOR 6
|
||||
#define SLC_ABORT 7
|
||||
#define SLC_EOF 8
|
||||
#define SLC_SUSP 9
|
||||
#define SLC_EC 10
|
||||
#define SLC_EL 11
|
||||
#define SLC_EW 12
|
||||
#define SLC_RP 13
|
||||
#define SLC_LNEXT 14
|
||||
#define SLC_XON 15
|
||||
#define SLC_XOFF 16
|
||||
#define SLC_FORW1 17
|
||||
#define SLC_FORW2 18
|
||||
|
||||
#define NSLC 18
|
||||
|
||||
/*
|
||||
* For backwards compatability, we define SLC_NAMES to be the
|
||||
* list of names if SLC_NAMES is not defined.
|
||||
*/
|
||||
#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
|
||||
"ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
|
||||
"LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
|
||||
#ifdef SLC_NAMES
|
||||
char *slc_names[] = {
|
||||
SLC_NAMELIST
|
||||
};
|
||||
#else
|
||||
extern char *slc_names[];
|
||||
#define SLC_NAMES SLC_NAMELIST
|
||||
#endif
|
||||
|
||||
#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
|
||||
#define SLC_NAME(x) slc_names[x]
|
||||
|
||||
#define SLC_NOSUPPORT 0
|
||||
#define SLC_CANTCHANGE 1
|
||||
#define SLC_VARIABLE 2
|
||||
#define SLC_DEFAULT 3
|
||||
#define SLC_LEVELBITS 0x03
|
||||
|
||||
#define SLC_FUNC 0
|
||||
#define SLC_FLAGS 1
|
||||
#define SLC_VALUE 2
|
||||
|
||||
#define SLC_ACK 0x80
|
||||
#define SLC_FLUSHIN 0x40
|
||||
#define SLC_FLUSHOUT 0x20
|
||||
|
||||
#define OLD_ENV_VAR 1
|
||||
#define OLD_ENV_VALUE 0
|
||||
#define NEW_ENV_VAR 0
|
||||
#define NEW_ENV_VALUE 1
|
||||
#define ENV_ESC 2
|
||||
#define ENV_USERVAR 3
|
||||
|
||||
/*
|
||||
* AUTHENTICATION suboptions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Who is authenticating who ...
|
||||
*/
|
||||
#define AUTH_WHO_CLIENT 0 /* Client authenticating server */
|
||||
#define AUTH_WHO_SERVER 1 /* Server authenticating client */
|
||||
#define AUTH_WHO_MASK 1
|
||||
|
||||
/*
|
||||
* amount of authentication done
|
||||
*/
|
||||
#define AUTH_HOW_ONE_WAY 0
|
||||
#define AUTH_HOW_MUTUAL 2
|
||||
#define AUTH_HOW_MASK 2
|
||||
|
||||
#define AUTHTYPE_NULL 0
|
||||
#define AUTHTYPE_KERBEROS_V4 1
|
||||
#define AUTHTYPE_KERBEROS_V5 2
|
||||
#define AUTHTYPE_SPX 3
|
||||
#define AUTHTYPE_MINK 4
|
||||
#define AUTHTYPE_CNT 5
|
||||
|
||||
#define AUTHTYPE_TEST 99
|
||||
|
||||
#ifdef AUTH_NAMES
|
||||
char *authtype_names[] = {
|
||||
"NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
|
||||
};
|
||||
#else
|
||||
extern char *authtype_names[];
|
||||
#endif
|
||||
|
||||
#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
|
||||
#define AUTHTYPE_NAME(x) authtype_names[x]
|
||||
|
||||
/*
|
||||
* ENCRYPTion suboptions
|
||||
*/
|
||||
#define ENCRYPT_IS 0 /* I pick encryption type ... */
|
||||
#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
|
||||
#define ENCRYPT_REPLY 2 /* Initial setup response */
|
||||
#define ENCRYPT_START 3 /* Am starting to send encrypted */
|
||||
#define ENCRYPT_END 4 /* Am ending encrypted */
|
||||
#define ENCRYPT_REQSTART 5 /* Request you start encrypting */
|
||||
#define ENCRYPT_REQEND 6 /* Request you send encrypting */
|
||||
#define ENCRYPT_ENC_KEYID 7
|
||||
#define ENCRYPT_DEC_KEYID 8
|
||||
#define ENCRYPT_CNT 9
|
||||
|
||||
#define ENCTYPE_ANY 0
|
||||
#define ENCTYPE_DES_CFB64 1
|
||||
#define ENCTYPE_DES_OFB64 2
|
||||
#define ENCTYPE_CNT 3
|
||||
|
||||
#ifdef ENCRYPT_NAMES
|
||||
char *encrypt_names[] = {
|
||||
"IS", "SUPPORT", "REPLY", "START", "END",
|
||||
"REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
|
||||
0,
|
||||
};
|
||||
char *enctype_names[] = {
|
||||
"ANY", "DES_CFB64", "DES_OFB64", 0,
|
||||
};
|
||||
#else
|
||||
extern char *encrypt_names[];
|
||||
extern char *enctype_names[];
|
||||
#endif
|
||||
|
||||
|
||||
#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
|
||||
#define ENCRYPT_NAME(x) encrypt_names[x]
|
||||
|
||||
#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
|
||||
#define ENCTYPE_NAME(x) enctype_names[x]
|
||||
|
||||
#endif /* !_TELNET_H_ */
|
96
contrib/telnet/libtelnet/auth-proto.h
Normal file
96
contrib/telnet/libtelnet/auth-proto.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)auth-proto.h 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(P)
|
||||
#ifdef __STDC__
|
||||
#define P(x) x
|
||||
#else
|
||||
#define P(x) ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(AUTHENTICATION)
|
||||
Authenticator *findauthenticator P((int, int));
|
||||
|
||||
void auth_init P((char *, int));
|
||||
int auth_cmd P((int, char **));
|
||||
void auth_request P((void));
|
||||
void auth_send P((unsigned char *, int));
|
||||
void auth_send_retry P((void));
|
||||
void auth_is P((unsigned char *, int));
|
||||
void auth_reply P((unsigned char *, int));
|
||||
void auth_finished P((Authenticator *, int));
|
||||
int auth_wait P((char *));
|
||||
void auth_disable_name P((char *));
|
||||
void auth_gen_printsub P((unsigned char *, int, unsigned char *, int));
|
||||
|
||||
#ifdef KRB4
|
||||
int kerberos4_init P((Authenticator *, int));
|
||||
int kerberos4_send P((Authenticator *));
|
||||
void kerberos4_is P((Authenticator *, unsigned char *, int));
|
||||
void kerberos4_reply P((Authenticator *, unsigned char *, int));
|
||||
int kerberos4_status P((Authenticator *, char *, int));
|
||||
void kerberos4_printsub P((unsigned char *, int, unsigned char *, int));
|
||||
#endif
|
||||
|
||||
#ifdef KRB5
|
||||
int kerberos5_init P((Authenticator *, int));
|
||||
int kerberos5_send P((Authenticator *));
|
||||
void kerberos5_is P((Authenticator *, unsigned char *, int));
|
||||
void kerberos5_reply P((Authenticator *, unsigned char *, int));
|
||||
int kerberos5_status P((Authenticator *, char *, int));
|
||||
void kerberos5_printsub P((unsigned char *, int, unsigned char *, int));
|
||||
#endif
|
||||
#endif
|
671
contrib/telnet/libtelnet/auth.c
Normal file
671
contrib/telnet/libtelnet/auth.c
Normal file
@ -0,0 +1,671 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)auth.c 8.3 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#if defined(AUTHENTICATION)
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#define AUTH_NAMES
|
||||
#include <arpa/telnet.h>
|
||||
#ifdef __STDC__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef NO_STRING_H
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#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;
|
||||
static 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 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
|
||||
# ifdef ENCRYPTION
|
||||
{ AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
|
||||
kerberos5_init,
|
||||
kerberos5_send,
|
||||
kerberos5_is,
|
||||
kerberos5_reply,
|
||||
kerberos5_status,
|
||||
kerberos5_printsub },
|
||||
# endif /* ENCRYPTION */
|
||||
{ AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
|
||||
kerberos5_init,
|
||||
kerberos5_send,
|
||||
kerberos5_is,
|
||||
kerberos5_reply,
|
||||
kerberos5_status,
|
||||
kerberos5_printsub },
|
||||
#endif
|
||||
#ifdef KRB4
|
||||
# ifdef ENCRYPTION
|
||||
{ AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
|
||||
kerberos4_init,
|
||||
kerberos4_send,
|
||||
kerberos4_is,
|
||||
kerberos4_reply,
|
||||
kerberos4_status,
|
||||
kerberos4_printsub },
|
||||
# endif /* ENCRYPTION */
|
||||
{ AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
|
||||
kerberos4_init,
|
||||
kerberos4_send,
|
||||
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(type, way)
|
||||
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(name, server)
|
||||
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(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(type, maskp)
|
||||
char *type;
|
||||
int *maskp;
|
||||
{
|
||||
register 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(type)
|
||||
char *type;
|
||||
{
|
||||
return(auth_onoff(type, 1));
|
||||
}
|
||||
|
||||
int
|
||||
auth_disable(type)
|
||||
char *type;
|
||||
{
|
||||
return(auth_onoff(type, 0));
|
||||
}
|
||||
|
||||
int
|
||||
auth_onoff(type, on)
|
||||
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(on)
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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;
|
||||
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(data, cnt)
|
||||
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((void *)_auth_send_data, (void *)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;
|
||||
}
|
||||
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);
|
||||
#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()
|
||||
{
|
||||
/*
|
||||
* 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(data, cnt)
|
||||
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(data, cnt)
|
||||
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(data, cnt)
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
Authenticator *ap;
|
||||
unsigned 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 %d length\r\n",
|
||||
Name, cnt, sizeof(savename)-1);
|
||||
return;
|
||||
}
|
||||
memmove((void *)savename, (void *)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(cp, len)
|
||||
unsigned char *cp;
|
||||
int len;
|
||||
{
|
||||
static unsigned char str_request[256+6]
|
||||
= { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, };
|
||||
register unsigned char *e = str_request + 4;
|
||||
register 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;
|
||||
net_write(str_request, e - str_request);
|
||||
printsub('>', &str_request[2], e - &str_request[2]);
|
||||
return(1);
|
||||
}
|
||||
|
||||
void
|
||||
auth_finished(ap, result)
|
||||
Authenticator *ap;
|
||||
int result;
|
||||
{
|
||||
if (!(authenticated = ap))
|
||||
authenticated = &NoAuth;
|
||||
validuser = result;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
auth_intr(sig)
|
||||
int sig;
|
||||
{
|
||||
auth_finished(0, AUTH_REJECT);
|
||||
}
|
||||
|
||||
int
|
||||
auth_wait(name)
|
||||
char *name;
|
||||
{
|
||||
if (auth_debug_mode)
|
||||
printf(">>>%s: in auth_wait.\r\n", Name);
|
||||
|
||||
if (Server && !authenticating)
|
||||
return(0);
|
||||
|
||||
(void) signal(SIGALRM, auth_intr);
|
||||
alarm(30);
|
||||
while (!authenticated)
|
||||
if (telnet_spin())
|
||||
break;
|
||||
alarm(0);
|
||||
(void) 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, validuser);
|
||||
return(validuser);
|
||||
}
|
||||
|
||||
void
|
||||
auth_debug(mode)
|
||||
int mode;
|
||||
{
|
||||
auth_debug_mode = mode;
|
||||
}
|
||||
|
||||
void
|
||||
auth_printsub(data, cnt, buf, buflen)
|
||||
unsigned char *data, *buf;
|
||||
int cnt, 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(data, cnt, buf, buflen)
|
||||
unsigned char *data, *buf;
|
||||
int cnt, buflen;
|
||||
{
|
||||
register 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++) {
|
||||
sprintf((char *)tbuf, " %d", *data);
|
||||
for (cp = tbuf; *cp && buflen > 0; --buflen)
|
||||
*buf++ = *cp++;
|
||||
if (buflen <= 0)
|
||||
return;
|
||||
}
|
||||
*buf = '\0';
|
||||
}
|
||||
#endif
|
87
contrib/telnet/libtelnet/auth.h
Normal file
87
contrib/telnet/libtelnet/auth.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)auth.h 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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 */
|
||||
|
||||
#if !defined(P)
|
||||
#ifdef __STDC__
|
||||
#define P(x) x
|
||||
#else
|
||||
#define P(x) ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct XauthP {
|
||||
int type;
|
||||
int way;
|
||||
int (*init) P((struct XauthP *, int));
|
||||
int (*send) P((struct XauthP *));
|
||||
void (*is) P((struct XauthP *, unsigned char *, int));
|
||||
void (*reply) P((struct XauthP *, unsigned char *, int));
|
||||
int (*status) P((struct XauthP *, char *, int));
|
||||
void (*printsub) P((unsigned char *, int, unsigned char *, int));
|
||||
} Authenticator;
|
||||
|
||||
#include "auth-proto.h"
|
||||
|
||||
extern auth_debug_mode;
|
||||
#endif
|
125
contrib/telnet/libtelnet/enc-proto.h
Normal file
125
contrib/telnet/libtelnet/enc-proto.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#if !defined(P)
|
||||
#ifdef __STDC__
|
||||
#define P(x) x
|
||||
#else
|
||||
#define P(x) ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
void encrypt_init P((char *, int));
|
||||
Encryptions *findencryption P((int));
|
||||
void encrypt_send_supprt P((void));
|
||||
void encrypt_auto P((int));
|
||||
void decrypt_auto P((int));
|
||||
void encrypt_is P((unsigned char *, int));
|
||||
void encrypt_reply P((unsigned char *, int));
|
||||
void encrypt_start_input P((int));
|
||||
void encrypt_session_key P((Session_Key *, int));
|
||||
void encrypt_end_input P((void));
|
||||
void encrypt_start_output P((int));
|
||||
void encrypt_end_output P((void));
|
||||
void encrypt_send_request_start P((void));
|
||||
void encrypt_send_request_end P((void));
|
||||
void encrypt_send_end P((void));
|
||||
void encrypt_wait P((void));
|
||||
void encrypt_send_support P((void));
|
||||
void encrypt_send_keyid P((int, unsigned char *, int, int));
|
||||
int net_write P((unsigned char *, int));
|
||||
|
||||
#ifdef TELENTD
|
||||
void encrypt_wait P((void));
|
||||
#else
|
||||
int encrypt_cmd P((int, char **));
|
||||
void encrypt_display P((void));
|
||||
#endif
|
||||
|
||||
void krbdes_encrypt P((unsigned char *, int));
|
||||
int krbdes_decrypt P((int));
|
||||
int krbdes_is P((unsigned char *, int));
|
||||
int krbdes_reply P((unsigned char *, int));
|
||||
void krbdes_init P((int));
|
||||
int krbdes_start P((int, int));
|
||||
void krbdes_session P((Session_Key *, int));
|
||||
void krbdes_printsub P((unsigned char *, int, unsigned char *, int));
|
||||
|
||||
void cfb64_encrypt P((unsigned char *, int));
|
||||
int cfb64_decrypt P((int));
|
||||
void cfb64_init P((int));
|
||||
int cfb64_start P((int, int));
|
||||
int cfb64_is P((unsigned char *, int));
|
||||
int cfb64_reply P((unsigned char *, int));
|
||||
void cfb64_session P((Session_Key *, int));
|
||||
int cfb64_keyid P((int, unsigned char *, int *));
|
||||
void cfb64_printsub P((unsigned char *, int, unsigned char *, int));
|
||||
|
||||
void ofb64_encrypt P((unsigned char *, int));
|
||||
int ofb64_decrypt P((int));
|
||||
void ofb64_init P((int));
|
||||
int ofb64_start P((int, int));
|
||||
int ofb64_is P((unsigned char *, int));
|
||||
int ofb64_reply P((unsigned char *, int));
|
||||
void ofb64_session P((Session_Key *, int));
|
||||
int ofb64_keyid P((int, unsigned char *, int *));
|
||||
void ofb64_printsub P((unsigned char *, int, unsigned char *, int));
|
||||
|
||||
int des_new_random_key P((Block));
|
||||
void des_set_random_generator_seed P((Block));
|
||||
void des_key_sched P((Block, Schedule));
|
||||
void des_ecb_encrypt P((Block, Block, Schedule, int));
|
||||
int des_string_to_key P((char *, Block));
|
||||
#endif /* ENCRYPTION */
|
724
contrib/telnet/libtelnet/enc_des.c
Normal file
724
contrib/telnet/libtelnet/enc_des.c
Normal file
@ -0,0 +1,724 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)enc_des.c 8.3 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
# ifdef AUTHENTICATION
|
||||
# ifdef DES_ENCRYPTION
|
||||
#include <arpa/telnet.h>
|
||||
#include <stdio.h>
|
||||
#ifdef __STDC__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "encrypt.h"
|
||||
#include "key-proto.h"
|
||||
#include "misc-proto.h"
|
||||
|
||||
extern 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 fb {
|
||||
Block krbdes_key;
|
||||
Schedule krbdes_sched;
|
||||
Block temp_feed;
|
||||
unsigned char fb_feed[64];
|
||||
int need_start;
|
||||
int state[2];
|
||||
int keyid[2];
|
||||
int once;
|
||||
struct stinfo {
|
||||
Block str_output;
|
||||
Block str_feed;
|
||||
Block str_iv;
|
||||
Block str_ikey;
|
||||
Schedule str_sched;
|
||||
int str_index;
|
||||
int str_flagshift;
|
||||
} 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 P((Block, struct stinfo *));
|
||||
void fb64_init P((struct fb *));
|
||||
static int fb64_start P((struct fb *, int, int));
|
||||
int fb64_is P((unsigned char *, int, struct fb *));
|
||||
int fb64_reply P((unsigned char *, int, struct fb *));
|
||||
static void fb64_session P((Session_Key *, int, struct fb *));
|
||||
void fb64_stream_key P((Block, struct stinfo *));
|
||||
int fb64_keyid P((int, unsigned char *, int *, struct fb *));
|
||||
|
||||
void
|
||||
cfb64_init(server)
|
||||
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(server)
|
||||
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(fbp)
|
||||
register struct fb *fbp;
|
||||
{
|
||||
memset((void *)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(dir, server)
|
||||
int dir;
|
||||
int server;
|
||||
{
|
||||
return(fb64_start(&fb[CFB], dir, server));
|
||||
}
|
||||
int
|
||||
ofb64_start(dir, server)
|
||||
int dir;
|
||||
int server;
|
||||
{
|
||||
return(fb64_start(&fb[OFB], dir, server));
|
||||
}
|
||||
|
||||
static int
|
||||
fb64_start(fbp, dir, server)
|
||||
struct fb *fbp;
|
||||
int dir;
|
||||
int server;
|
||||
{
|
||||
Block b;
|
||||
int x;
|
||||
unsigned char *p;
|
||||
register 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.
|
||||
*/
|
||||
des_new_random_key(fbp->temp_feed);
|
||||
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(Block); ++x) {
|
||||
if ((*p++ = fbp->temp_feed[x]) == IAC)
|
||||
*p++ = IAC;
|
||||
}
|
||||
*p++ = IAC;
|
||||
*p++ = SE;
|
||||
printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]);
|
||||
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(data, cnt)
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
return(fb64_is(data, cnt, &fb[CFB]));
|
||||
}
|
||||
int
|
||||
ofb64_is(data, cnt)
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
return(fb64_is(data, cnt, &fb[OFB]));
|
||||
}
|
||||
|
||||
int
|
||||
fb64_is(data, cnt, fbp)
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
struct fb *fbp;
|
||||
{
|
||||
int x;
|
||||
unsigned char *p;
|
||||
Block b;
|
||||
register int state = fbp->state[DIR_DECRYPT-1];
|
||||
|
||||
if (cnt-- < 1)
|
||||
goto failure;
|
||||
|
||||
switch (*data++) {
|
||||
case FB64_IV:
|
||||
if (cnt != sizeof(Block)) {
|
||||
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((void *)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]);
|
||||
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]);
|
||||
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(data, cnt)
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
return(fb64_reply(data, cnt, &fb[CFB]));
|
||||
}
|
||||
int
|
||||
ofb64_reply(data, cnt)
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
return(fb64_reply(data, cnt, &fb[OFB]));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fb64_reply(data, cnt, fbp)
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
struct fb *fbp;
|
||||
{
|
||||
int x;
|
||||
unsigned char *p;
|
||||
Block b;
|
||||
register 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(Block));
|
||||
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(key, server)
|
||||
Session_Key *key;
|
||||
int server;
|
||||
{
|
||||
fb64_session(key, server, &fb[CFB]);
|
||||
}
|
||||
|
||||
void
|
||||
ofb64_session(key, server)
|
||||
Session_Key *key;
|
||||
int server;
|
||||
{
|
||||
fb64_session(key, server, &fb[OFB]);
|
||||
}
|
||||
|
||||
static void
|
||||
fb64_session(key, server, fbp)
|
||||
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;
|
||||
}
|
||||
memmove((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block));
|
||||
|
||||
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) {
|
||||
des_set_random_generator_seed(fbp->krbdes_key);
|
||||
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(dir, kp, lenp)
|
||||
int dir, *lenp;
|
||||
unsigned char *kp;
|
||||
{
|
||||
return(fb64_keyid(dir, kp, lenp, &fb[CFB]));
|
||||
}
|
||||
|
||||
int
|
||||
ofb64_keyid(dir, kp, lenp)
|
||||
int dir, *lenp;
|
||||
unsigned char *kp;
|
||||
{
|
||||
return(fb64_keyid(dir, kp, lenp, &fb[OFB]));
|
||||
}
|
||||
|
||||
int
|
||||
fb64_keyid(dir, kp, lenp, fbp)
|
||||
int dir, *lenp;
|
||||
unsigned char *kp;
|
||||
struct fb *fbp;
|
||||
{
|
||||
register 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(data, cnt, buf, buflen, type)
|
||||
unsigned char *data, *buf, *type;
|
||||
int cnt, buflen;
|
||||
{
|
||||
char lbuf[32];
|
||||
register int i;
|
||||
char *cp;
|
||||
|
||||
buf[buflen-1] = '\0'; /* make sure it's NULL terminated */
|
||||
buflen -= 1;
|
||||
|
||||
switch(data[2]) {
|
||||
case FB64_IV:
|
||||
sprintf(lbuf, "%s_IV", type);
|
||||
cp = lbuf;
|
||||
goto common;
|
||||
|
||||
case FB64_IV_OK:
|
||||
sprintf(lbuf, "%s_IV_OK", type);
|
||||
cp = lbuf;
|
||||
goto common;
|
||||
|
||||
case FB64_IV_BAD:
|
||||
sprintf(lbuf, "%s_IV_BAD", type);
|
||||
cp = lbuf;
|
||||
goto common;
|
||||
|
||||
default:
|
||||
sprintf(lbuf, " %d (unknown)", data[2]);
|
||||
cp = lbuf;
|
||||
common:
|
||||
for (; (buflen > 0) && (*buf = *cp++); buf++)
|
||||
buflen--;
|
||||
for (i = 3; i < cnt; i++) {
|
||||
sprintf(lbuf, " %d", data[i]);
|
||||
for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++)
|
||||
buflen--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cfb64_printsub(data, cnt, buf, buflen)
|
||||
unsigned char *data, *buf;
|
||||
int cnt, buflen;
|
||||
{
|
||||
fb64_printsub(data, cnt, buf, buflen, "CFB64");
|
||||
}
|
||||
|
||||
void
|
||||
ofb64_printsub(data, cnt, buf, buflen)
|
||||
unsigned char *data, *buf;
|
||||
int cnt, buflen;
|
||||
{
|
||||
fb64_printsub(data, cnt, buf, buflen, "OFB64");
|
||||
}
|
||||
|
||||
void
|
||||
fb64_stream_iv(seed, stp)
|
||||
Block seed;
|
||||
register struct stinfo *stp;
|
||||
{
|
||||
|
||||
memmove((void *)stp->str_iv, (void *)seed, sizeof(Block));
|
||||
memmove((void *)stp->str_output, (void *)seed, sizeof(Block));
|
||||
|
||||
des_key_sched(stp->str_ikey, stp->str_sched);
|
||||
|
||||
stp->str_index = sizeof(Block);
|
||||
}
|
||||
|
||||
void
|
||||
fb64_stream_key(key, stp)
|
||||
Block key;
|
||||
register struct stinfo *stp;
|
||||
{
|
||||
memmove((void *)stp->str_ikey, (void *)key, sizeof(Block));
|
||||
des_key_sched(key, stp->str_sched);
|
||||
|
||||
memmove((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block));
|
||||
|
||||
stp->str_index = sizeof(Block);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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(s, c)
|
||||
register unsigned char *s;
|
||||
int c;
|
||||
{
|
||||
register struct stinfo *stp = &fb[CFB].streams[DIR_ENCRYPT-1];
|
||||
register int index;
|
||||
|
||||
index = stp->str_index;
|
||||
while (c-- > 0) {
|
||||
if (index == sizeof(Block)) {
|
||||
Block b;
|
||||
des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1);
|
||||
memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
|
||||
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(data)
|
||||
int data;
|
||||
{
|
||||
register 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(Block)) {
|
||||
Block b;
|
||||
des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1);
|
||||
memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
|
||||
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(s, c)
|
||||
register unsigned char *s;
|
||||
int c;
|
||||
{
|
||||
register struct stinfo *stp = &fb[OFB].streams[DIR_ENCRYPT-1];
|
||||
register int index;
|
||||
|
||||
index = stp->str_index;
|
||||
while (c-- > 0) {
|
||||
if (index == sizeof(Block)) {
|
||||
Block b;
|
||||
des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1);
|
||||
memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
|
||||
index = 0;
|
||||
}
|
||||
*s++ ^= stp->str_feed[index];
|
||||
index++;
|
||||
}
|
||||
stp->str_index = index;
|
||||
}
|
||||
|
||||
int
|
||||
ofb64_decrypt(data)
|
||||
int data;
|
||||
{
|
||||
register 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(Block)) {
|
||||
Block b;
|
||||
des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1);
|
||||
memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
|
||||
stp->str_index = 1; /* Next time will be 1 */
|
||||
index = 0; /* But now use 0 */
|
||||
}
|
||||
|
||||
return(data ^ stp->str_feed[index]);
|
||||
}
|
||||
# endif /* DES_ENCRYPTION */
|
||||
# endif /* AUTHENTICATION */
|
||||
#endif /* ENCRYPTION */
|
1000
contrib/telnet/libtelnet/encrypt.c
Normal file
1000
contrib/telnet/libtelnet/encrypt.c
Normal file
File diff suppressed because it is too large
Load Diff
108
contrib/telnet/libtelnet/encrypt.h
Normal file
108
contrib/telnet/libtelnet/encrypt.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)encrypt.h 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
# ifndef __ENCRYPTION__
|
||||
# define __ENCRYPTION__
|
||||
|
||||
#define DIR_DECRYPT 1
|
||||
#define DIR_ENCRYPT 2
|
||||
|
||||
typedef unsigned char Block[8];
|
||||
typedef unsigned char *BlockT;
|
||||
typedef struct { Block _; } Schedule[16];
|
||||
|
||||
#define VALIDKEY(key) ( key[0] | key[1] | key[2] | key[3] | \
|
||||
key[4] | key[5] | key[6] | key[7])
|
||||
|
||||
#define SAMEKEY(k1, k2) (!bcmp((void *)k1, (void *)k2, sizeof(Block)))
|
||||
|
||||
typedef struct {
|
||||
short type;
|
||||
int length;
|
||||
unsigned char *data;
|
||||
} Session_Key;
|
||||
|
||||
# if !defined(P)
|
||||
# ifdef __STDC__
|
||||
# define P(x) x
|
||||
# else
|
||||
# define P(x) ()
|
||||
# endif
|
||||
# endif
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int type;
|
||||
void (*output) P((unsigned char *, int));
|
||||
int (*input) P((int));
|
||||
void (*init) P((int));
|
||||
int (*start) P((int, int));
|
||||
int (*is) P((unsigned char *, int));
|
||||
int (*reply) P((unsigned char *, int));
|
||||
void (*session) P((Session_Key *, int));
|
||||
int (*keyid) P((int, unsigned char *, int *));
|
||||
void (*printsub) P((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) P((int));
|
||||
extern void (*encrypt_output) P((unsigned char *, int));
|
||||
# endif /* __ENCRYPTION__ */
|
||||
#endif /* ENCRYPTION */
|
105
contrib/telnet/libtelnet/genget.c
Normal file
105
contrib/telnet/libtelnet/genget.c
Normal file
@ -0,0 +1,105 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)genget.c 8.2 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#define LOWER(x) (isupper(x) ? tolower(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(s1, s2)
|
||||
register char *s1, *s2;
|
||||
{
|
||||
register int n = 0;
|
||||
char *os1;
|
||||
register 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(name, table, stlen)
|
||||
char *name; /* name to match */
|
||||
char **table; /* name entry in table */
|
||||
int stlen;
|
||||
{
|
||||
register char **c, **found;
|
||||
register 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(s)
|
||||
char *s;
|
||||
{
|
||||
return((char **)s == &ambiguous);
|
||||
}
|
68
contrib/telnet/libtelnet/getent.c
Normal file
68
contrib/telnet/libtelnet/getent.c
Normal file
@ -0,0 +1,68 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)getent.c 8.2 (Berkeley) 12/15/93";
|
||||
#endif /* not lint */
|
||||
|
||||
static char *area;
|
||||
|
||||
/*ARGSUSED*/
|
||||
getent(cp, name)
|
||||
char *cp, *name;
|
||||
{
|
||||
#ifdef HAS_CGETENT
|
||||
char *dba[2];
|
||||
|
||||
dba[0] = "/etc/gettytab";
|
||||
dba[1] = 0;
|
||||
return((cgetent(&area, dba, name) == 0) ? 1 : 0);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef SOLARIS
|
||||
/*ARGSUSED*/
|
||||
char *
|
||||
getstr(id, cpp)
|
||||
char *id, **cpp;
|
||||
{
|
||||
# ifdef HAS_CGETENT
|
||||
char *answer;
|
||||
return((cgetstr(area, id, &answer) > 0) ? answer : 0);
|
||||
# else
|
||||
return(0);
|
||||
# endif
|
||||
}
|
||||
#endif
|
560
contrib/telnet/libtelnet/kerberos.c
Normal file
560
contrib/telnet/libtelnet/kerberos.c
Normal file
@ -0,0 +1,560 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)kerberos.c 8.3 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef KRB4
|
||||
#include <sys/types.h>
|
||||
#include <arpa/telnet.h>
|
||||
#include <stdio.h>
|
||||
#include <des.h> /* BSD wont include this in krb.h, so we do it here */
|
||||
#include <krb.h>
|
||||
#ifdef __STDC__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef NO_STRING_H
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "encrypt.h"
|
||||
#include "auth.h"
|
||||
#include "misc.h"
|
||||
|
||||
int kerberos4_cksum P((unsigned char *, int));
|
||||
int krb_mk_req P((KTEXT, char *, char *, char *, u_long));
|
||||
int krb_rd_req P((KTEXT, char *, char *, u_long, AUTH_DAT *, char *));
|
||||
int krb_kntoln P((AUTH_DAT *, char *));
|
||||
int krb_get_cred P((char *, char *, char *, CREDENTIALS *));
|
||||
int krb_get_lrealm P((char *, int));
|
||||
int kuserok P((AUTH_DAT *, char *));
|
||||
|
||||
extern auth_debug_mode;
|
||||
|
||||
static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
|
||||
AUTHTYPE_KERBEROS_V4, };
|
||||
static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
|
||||
TELQUAL_NAME, };
|
||||
|
||||
#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_SERVICE_NAME "rcmd"
|
||||
|
||||
static KTEXT_ST auth;
|
||||
static char name[ANAME_SZ];
|
||||
static AUTH_DAT adat = { 0 };
|
||||
#ifdef ENCRYPTION
|
||||
static Block session_key = { 0 };
|
||||
static Schedule sched;
|
||||
static Block challenge = { 0 };
|
||||
#endif /* ENCRYPTION */
|
||||
|
||||
static int
|
||||
Data(ap, type, d, c)
|
||||
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((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(net_write(str_data, p - str_data));
|
||||
}
|
||||
|
||||
int
|
||||
kerberos4_init(ap, server)
|
||||
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;
|
||||
|
||||
int
|
||||
kerberos4_send(ap)
|
||||
Authenticator *ap;
|
||||
{
|
||||
KTEXT_ST auth;
|
||||
#ifdef ENCRYPTION
|
||||
Block enckey;
|
||||
#endif /* ENCRYPTION */
|
||||
char instance[INST_SZ];
|
||||
char *realm;
|
||||
char *krb_realmofhost();
|
||||
char *krb_get_phost();
|
||||
CREDENTIALS cred;
|
||||
int r;
|
||||
|
||||
printf("[ Trying KERBEROS4 ... ]\n");
|
||||
if (!UserNameRequested) {
|
||||
if (auth_debug_mode) {
|
||||
printf("Kerberos V4: no user name supplied\r\n");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
memset(instance, 0, sizeof(instance));
|
||||
|
||||
if (realm = krb_get_phost(RemoteHostName))
|
||||
strncpy(instance, realm, sizeof(instance));
|
||||
|
||||
instance[sizeof(instance)-1] = '\0';
|
||||
|
||||
realm = dest_realm ? dest_realm : krb_realmofhost(RemoteHostName);
|
||||
|
||||
if (!realm) {
|
||||
printf("Kerberos V4: no realm for %s\r\n", RemoteHostName);
|
||||
return(0);
|
||||
}
|
||||
if (r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0L)) {
|
||||
printf("mk_req failed: %s\r\n", krb_err_txt[r]);
|
||||
return(0);
|
||||
}
|
||||
if (r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred)) {
|
||||
printf("get_cred failed: %s\r\n", krb_err_txt[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
|
||||
/*
|
||||
* If we are doing mutual authentication, get set up to send
|
||||
* the challenge, and verify it when the response comes back.
|
||||
*/
|
||||
if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
|
||||
register int i;
|
||||
|
||||
des_key_sched(cred.session, sched);
|
||||
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);
|
||||
/*
|
||||
* Increment the challenge by 1, and encrypt it for
|
||||
* later comparison.
|
||||
*/
|
||||
for (i = 7; i >= 0; --i) {
|
||||
register int x;
|
||||
x = (unsigned int)challenge[i] + 1;
|
||||
challenge[i] = x; /* ignore overflow */
|
||||
if (x < 256) /* if no overflow, all done */
|
||||
break;
|
||||
}
|
||||
des_ecb_encrypt(challenge, challenge, sched, 1);
|
||||
}
|
||||
#endif /* ENCRYPTION */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
kerberos4_is(ap, data, cnt)
|
||||
Authenticator *ap;
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
#ifdef ENCRYPTION
|
||||
Session_Key skey;
|
||||
Block datablock;
|
||||
#endif /* ENCRYPTION */
|
||||
char realm[REALM_SZ];
|
||||
char instance[INST_SZ];
|
||||
int r;
|
||||
|
||||
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((void *)auth.dat, (void *)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");
|
||||
}
|
||||
instance[0] = '*'; instance[1] = 0;
|
||||
if (r = krb_rd_req(&auth, KRB_SERVICE_NAME,
|
||||
instance, 0, &adat, "")) {
|
||||
if (auth_debug_mode)
|
||||
printf("Kerberos failed him as %s\r\n", name);
|
||||
Data(ap, KRB_REJECT, (void *)krb_err_txt[r], -1);
|
||||
auth_finished(ap, AUTH_REJECT);
|
||||
return;
|
||||
}
|
||||
#ifdef ENCRYPTION
|
||||
memmove((void *)session_key, (void *)adat.session, sizeof(Block));
|
||||
#endif /* ENCRYPTION */
|
||||
krb_kntoln(&adat, name);
|
||||
|
||||
if (UserNameRequested && !kuserok(&adat, UserNameRequested))
|
||||
Data(ap, KRB_ACCEPT, (void *)0, 0);
|
||||
else
|
||||
Data(ap, KRB_REJECT,
|
||||
(void *)"user is not authorized", -1);
|
||||
auth_finished(ap, AUTH_USER);
|
||||
break;
|
||||
|
||||
case KRB_CHALLENGE:
|
||||
#ifndef ENCRYPTION
|
||||
Data(ap, KRB_RESPONSE, (void *)0, 0);
|
||||
#else /* ENCRYPTION */
|
||||
if (!VALIDKEY(session_key)) {
|
||||
/*
|
||||
* We don't have a valid session key, so just
|
||||
* send back a response with an empty session
|
||||
* key.
|
||||
*/
|
||||
Data(ap, KRB_RESPONSE, (void *)0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the random number generator since it's
|
||||
* used later on by the encryption routine.
|
||||
*/
|
||||
des_init_random_number_generator(session_key);
|
||||
des_key_sched(session_key, sched);
|
||||
memmove((void *)datablock, (void *)data, sizeof(Block));
|
||||
/*
|
||||
* Take the received encrypted challenge, and encrypt
|
||||
* it again to get a unique session_key for the
|
||||
* ENCRYPT option.
|
||||
*/
|
||||
des_ecb_encrypt(datablock, session_key, sched, 1);
|
||||
skey.type = SK_DES;
|
||||
skey.length = 8;
|
||||
skey.data = session_key;
|
||||
encrypt_session_key(&skey, 1);
|
||||
/*
|
||||
* Now decrypt the received encrypted challenge,
|
||||
* increment by one, re-encrypt it and send it back.
|
||||
*/
|
||||
des_ecb_encrypt(datablock, challenge, sched, 0);
|
||||
for (r = 7; r >= 0; r--) {
|
||||
register int t;
|
||||
t = (unsigned int)challenge[r] + 1;
|
||||
challenge[r] = t; /* ignore overflow */
|
||||
if (t < 256) /* if no overflow, all done */
|
||||
break;
|
||||
}
|
||||
des_ecb_encrypt(challenge, challenge, sched, 1);
|
||||
Data(ap, KRB_RESPONSE, (void *)challenge, sizeof(challenge));
|
||||
#endif /* ENCRYPTION */
|
||||
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(ap, data, cnt)
|
||||
Authenticator *ap;
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
#ifdef ENCRYPTION
|
||||
Session_Key skey;
|
||||
#endif /* ENCRYPTION */
|
||||
|
||||
if (cnt-- < 1)
|
||||
return;
|
||||
switch (*data++) {
|
||||
case KRB_REJECT:
|
||||
if (cnt > 0) {
|
||||
printf("[ Kerberos V4 refuses authentication because %.*s ]\r\n",
|
||||
cnt, data);
|
||||
} else
|
||||
printf("[ Kerberos V4 refuses authentication ]\r\n");
|
||||
auth_send_retry();
|
||||
return;
|
||||
case KRB_ACCEPT:
|
||||
printf("[ Kerberos V4 accepts you ]\n");
|
||||
if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
|
||||
/*
|
||||
* Send over the encrypted challenge.
|
||||
*/
|
||||
#ifndef ENCRYPTION
|
||||
Data(ap, KRB_CHALLENGE, (void *)0, 0);
|
||||
#else /* ENCRYPTION */
|
||||
Data(ap, KRB_CHALLENGE, (void *)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);
|
||||
#endif /* ENCRYPTION */
|
||||
return;
|
||||
}
|
||||
auth_finished(ap, AUTH_USER);
|
||||
return;
|
||||
case KRB_RESPONSE:
|
||||
#ifdef ENCRYPTION
|
||||
/*
|
||||
* Verify that the response to the challenge is correct.
|
||||
*/
|
||||
if ((cnt != sizeof(Block)) ||
|
||||
(0 != memcmp((void *)data, (void *)challenge,
|
||||
sizeof(challenge))))
|
||||
{
|
||||
#endif /* ENCRYPTION */
|
||||
printf("[ Kerberos V4 challenge failed!!! ]\r\n");
|
||||
auth_send_retry();
|
||||
return;
|
||||
#ifdef ENCRYPTION
|
||||
}
|
||||
printf("[ Kerberos V4 challenge successful ]\r\n");
|
||||
auth_finished(ap, AUTH_USER);
|
||||
#endif /* ENCRYPTION */
|
||||
break;
|
||||
default:
|
||||
if (auth_debug_mode)
|
||||
printf("Unknown Kerberos option %d\r\n", data[-1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
kerberos4_status(ap, name, level)
|
||||
Authenticator *ap;
|
||||
char *name;
|
||||
int level;
|
||||
{
|
||||
if (level < AUTH_USER)
|
||||
return(level);
|
||||
|
||||
if (UserNameRequested && !kuserok(&adat, UserNameRequested)) {
|
||||
strcpy(name, UserNameRequested);
|
||||
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(data, cnt, buf, buflen)
|
||||
unsigned char *data, *buf;
|
||||
int cnt, buflen;
|
||||
{
|
||||
char lbuf[32];
|
||||
register int i;
|
||||
|
||||
buf[buflen-1] = '\0'; /* make sure its NULL terminated */
|
||||
buflen -= 1;
|
||||
|
||||
switch(data[3]) {
|
||||
case KRB_REJECT: /* Rejected (reason might follow) */
|
||||
strncpy((char *)buf, " REJECT ", buflen);
|
||||
goto common;
|
||||
|
||||
case KRB_ACCEPT: /* Accepted (name might follow) */
|
||||
strncpy((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 */
|
||||
strncpy((char *)buf, " AUTH", buflen);
|
||||
goto common2;
|
||||
|
||||
case KRB_CHALLENGE:
|
||||
strncpy((char *)buf, " CHALLENGE", buflen);
|
||||
goto common2;
|
||||
|
||||
case KRB_RESPONSE:
|
||||
strncpy((char *)buf, " RESPONSE", buflen);
|
||||
goto common2;
|
||||
|
||||
default:
|
||||
sprintf(lbuf, " %d (unknown)", data[3]);
|
||||
strncpy((char *)buf, lbuf, buflen);
|
||||
common2:
|
||||
BUMP(buf, buflen);
|
||||
for (i = 4; i < cnt; i++) {
|
||||
sprintf(lbuf, " %d", data[i]);
|
||||
strncpy((char *)buf, lbuf, buflen);
|
||||
BUMP(buf, buflen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
kerberos4_cksum(d, n)
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef notdef
|
||||
|
||||
prkey(msg, key)
|
||||
char *msg;
|
||||
unsigned char *key;
|
||||
{
|
||||
register int i;
|
||||
printf("%s:", msg);
|
||||
for (i = 0; i < 8; i++)
|
||||
printf(" %3d", key[i]);
|
||||
printf("\r\n");
|
||||
}
|
||||
#endif
|
764
contrib/telnet/libtelnet/kerberos5.c
Normal file
764
contrib/telnet/libtelnet/kerberos5.c
Normal file
@ -0,0 +1,764 @@
|
||||
/*
|
||||
* $Source: /mit/krb5/.cvsroot/src/appl/telnet/libtelnet/kerberos5.c,v $
|
||||
* $Author: tytso $
|
||||
* $Id: kerberos5.c,v 1.1 1997/09/04 06:11:15 markm Exp $
|
||||
*/
|
||||
|
||||
#if !defined(lint) && !defined(SABER)
|
||||
static
|
||||
#ifdef __STDC__
|
||||
const
|
||||
#endif
|
||||
char rcsid_kerberos5_c[] = "$Id: kerberos5.c,v 1.1 1997/09/04 06:11:15 markm Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)kerberos5.c 8.3 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef KRB5
|
||||
#include <arpa/telnet.h>
|
||||
#include <stdio.h>
|
||||
#include <krb5/krb5.h>
|
||||
#include <krb5/asn1.h>
|
||||
#include <krb5/crc-32.h>
|
||||
#include <krb5/los-proto.h>
|
||||
#include <krb5/ext-proto.h>
|
||||
#include <com_err.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* kerberos 5 include files (ext-proto.h) will get an appropriate stdlib.h
|
||||
and string.h/strings.h */
|
||||
|
||||
#include "encrypt.h"
|
||||
#include "auth.h"
|
||||
#include "misc.h"
|
||||
|
||||
extern auth_debug_mode;
|
||||
|
||||
#ifdef FORWARD
|
||||
int forward_flags = 0; /* Flags get set in telnet/main.c on -f and -F */
|
||||
|
||||
/* 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();
|
||||
|
||||
#endif /* FORWARD */
|
||||
|
||||
static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
|
||||
AUTHTYPE_KERBEROS_V5, };
|
||||
/*static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
|
||||
TELQUAL_NAME, };*/
|
||||
|
||||
#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. */
|
||||
|
||||
#ifdef FORWARD
|
||||
#define KRB_FORWARD 4 /* Forwarded credentials follow */
|
||||
#define KRB_FORWARD_ACCEPT 5 /* Forwarded credentials accepted */
|
||||
#define KRB_FORWARD_REJECT 6 /* Forwarded credentials rejected */
|
||||
#endif /* FORWARD */
|
||||
|
||||
static krb5_data auth;
|
||||
/* telnetd gets session key from here */
|
||||
static krb5_tkt_authent *authdat = NULL;
|
||||
/* telnet matches the AP_REQ and AP_REP with this */
|
||||
static krb5_authenticator authenticator;
|
||||
|
||||
/* some compilers can't hack void *, so we use the Kerberos krb5_pointer,
|
||||
which is either void * or char *, depending on the compiler. */
|
||||
|
||||
#define Voidptr krb5_pointer
|
||||
|
||||
Block session_key;
|
||||
|
||||
static int
|
||||
Data(ap, type, d, c)
|
||||
Authenticator *ap;
|
||||
int type;
|
||||
Voidptr d;
|
||||
int c;
|
||||
{
|
||||
unsigned char *p = str_data + 4;
|
||||
unsigned char *cd = (unsigned char *)d;
|
||||
|
||||
if (c == -1)
|
||||
c = strlen((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(net_write(str_data, p - str_data));
|
||||
}
|
||||
|
||||
int
|
||||
kerberos5_init(ap, server)
|
||||
Authenticator *ap;
|
||||
int server;
|
||||
{
|
||||
if (server)
|
||||
str_data[3] = TELQUAL_REPLY;
|
||||
else
|
||||
str_data[3] = TELQUAL_IS;
|
||||
krb5_init_ets();
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
kerberos5_send(ap)
|
||||
Authenticator *ap;
|
||||
{
|
||||
char **realms;
|
||||
char *name;
|
||||
char *p1, *p2;
|
||||
krb5_checksum ksum;
|
||||
krb5_octet sum[CRC32_CKSUM_LENGTH];
|
||||
krb5_principal server;
|
||||
krb5_error_code r;
|
||||
krb5_ccache ccache;
|
||||
krb5_creds creds; /* telnet gets session key from here */
|
||||
extern krb5_flags krb5_kdc_default_options;
|
||||
int ap_opts;
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
krb5_keyblock *newkey = 0;
|
||||
#endif /* ENCRYPTION */
|
||||
|
||||
ksum.checksum_type = CKSUMTYPE_CRC32;
|
||||
ksum.contents = sum;
|
||||
ksum.length = sizeof(sum);
|
||||
memset((Voidptr )sum, 0, sizeof(sum));
|
||||
|
||||
if (!UserNameRequested) {
|
||||
if (auth_debug_mode) {
|
||||
printf("Kerberos V5: no user name supplied\r\n");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (r = krb5_cc_default(&ccache)) {
|
||||
if (auth_debug_mode) {
|
||||
printf("Kerberos V5: could not get default ccache\r\n");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
if ((name = malloc(strlen(RemoteHostName)+1)) == NULL) {
|
||||
if (auth_debug_mode)
|
||||
printf("Out of memory for hostname in Kerberos V5\r\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (r = krb5_get_host_realm(RemoteHostName, &realms)) {
|
||||
if (auth_debug_mode)
|
||||
printf("Kerberos V5: no realm for %s\r\n", RemoteHostName);
|
||||
free(name);
|
||||
return(0);
|
||||
}
|
||||
|
||||
p1 = RemoteHostName;
|
||||
p2 = name;
|
||||
|
||||
while (*p2 = *p1++) {
|
||||
if (isupper(*p2))
|
||||
*p2 |= 040;
|
||||
++p2;
|
||||
}
|
||||
|
||||
if (r = krb5_build_principal_ext(&server,
|
||||
strlen(realms[0]), realms[0],
|
||||
4, "host",
|
||||
p2 - name, name,
|
||||
0)) {
|
||||
if (auth_debug_mode) {
|
||||
printf("Kerberos V5: failure setting up principal (%s)\r\n",
|
||||
error_message(r));
|
||||
}
|
||||
free(name);
|
||||
krb5_free_host_realm(realms);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
memset((char *)&creds, 0, sizeof(creds));
|
||||
creds.server = server;
|
||||
|
||||
if (r = krb5_cc_get_principal(ccache, &creds.client)) {
|
||||
if (auth_debug_mode) {
|
||||
printf("Kerberos V5: failure on principal (%s)\r\n",
|
||||
error_message(r));
|
||||
}
|
||||
free(name);
|
||||
krb5_free_principal(server);
|
||||
krb5_free_host_realm(realms);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (r = krb5_get_credentials(krb5_kdc_default_options, ccache, &creds)) {
|
||||
if (auth_debug_mode) {
|
||||
printf("Kerberos V5: failure on credentials(%d)\r\n",r);
|
||||
}
|
||||
free(name);
|
||||
krb5_free_host_realm(realms);
|
||||
krb5_free_principal(server);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
|
||||
ap_opts = AP_OPTS_MUTUAL_REQUIRED;
|
||||
else
|
||||
ap_opts = 0;
|
||||
|
||||
r = krb5_mk_req_extended(ap_opts, &ksum, krb5_kdc_default_options, 0,
|
||||
#ifdef ENCRYPTION
|
||||
&newkey,
|
||||
#else /* ENCRYPTION */
|
||||
0,
|
||||
#endif /* ENCRYPTION */
|
||||
ccache, &creds, &authenticator, &auth);
|
||||
/* don't let the key get freed if we clean up the authenticator */
|
||||
authenticator.subkey = 0;
|
||||
|
||||
free(name);
|
||||
krb5_free_host_realm(realms);
|
||||
krb5_free_principal(server);
|
||||
#ifdef ENCRYPTION
|
||||
if (newkey) {
|
||||
/* keep the key in our private storage, but don't use it
|
||||
yet---see kerberos5_reply() below */
|
||||
if (newkey->keytype != KEYTYPE_DES) {
|
||||
if (creds.keyblock.keytype == KEYTYPE_DES)
|
||||
/* use the session key in credentials instead */
|
||||
memmove((char *)session_key,
|
||||
(char *)creds.keyblock.contents, sizeof(Block));
|
||||
else
|
||||
/* XXX ? */;
|
||||
} else {
|
||||
memmove((char *)session_key, (char *)newkey->contents,
|
||||
sizeof(Block));
|
||||
}
|
||||
krb5_free_keyblock(newkey);
|
||||
}
|
||||
#endif /* ENCRYPTION */
|
||||
if (r) {
|
||||
if (auth_debug_mode) {
|
||||
printf("Kerberos V5: mk_req failed (%s)\r\n",
|
||||
error_message(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 (!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);
|
||||
}
|
||||
|
||||
void
|
||||
kerberos5_is(ap, data, cnt)
|
||||
Authenticator *ap;
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
int r;
|
||||
struct hostent *hp;
|
||||
char *p1, *p2;
|
||||
static char *realm = NULL;
|
||||
krb5_principal server;
|
||||
krb5_ap_rep_enc_part reply;
|
||||
krb5_data outbuf;
|
||||
#ifdef ENCRYPTION
|
||||
Session_Key skey;
|
||||
#endif /* ENCRYPTION */
|
||||
char *name;
|
||||
char *getenv();
|
||||
krb5_data inbuf;
|
||||
|
||||
if (cnt-- < 1)
|
||||
return;
|
||||
switch (*data++) {
|
||||
case KRB_AUTH:
|
||||
auth.data = (char *)data;
|
||||
auth.length = cnt;
|
||||
|
||||
if (!(hp = gethostbyname(LocalHostName))) {
|
||||
if (auth_debug_mode)
|
||||
printf("Cannot resolve local host name\r\n");
|
||||
Data(ap, KRB_REJECT, "Unknown local hostname.", -1);
|
||||
auth_finished(ap, AUTH_REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!realm && (krb5_get_default_realm(&realm))) {
|
||||
if (auth_debug_mode)
|
||||
printf("Could not get default realm\r\n");
|
||||
Data(ap, KRB_REJECT, "Could not get default realm.", -1);
|
||||
auth_finished(ap, AUTH_REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((name = malloc(strlen(hp->h_name)+1)) == NULL) {
|
||||
if (auth_debug_mode)
|
||||
printf("Out of memory for hostname in Kerberos V5\r\n");
|
||||
Data(ap, KRB_REJECT, "Out of memory.", -1);
|
||||
auth_finished(ap, AUTH_REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
p1 = hp->h_name;
|
||||
p2 = name;
|
||||
|
||||
while (*p2 = *p1++) {
|
||||
if (isupper(*p2))
|
||||
*p2 |= 040;
|
||||
++p2;
|
||||
}
|
||||
|
||||
if (authdat)
|
||||
krb5_free_tkt_authent(authdat);
|
||||
|
||||
r = krb5_build_principal_ext(&server,
|
||||
strlen(realm), realm,
|
||||
4, "host",
|
||||
p2 - name, name,
|
||||
0);
|
||||
if (!r) {
|
||||
r = krb5_rd_req_simple(&auth, server, 0, &authdat);
|
||||
krb5_free_principal(server);
|
||||
}
|
||||
if (r) {
|
||||
char errbuf[128];
|
||||
|
||||
errout:
|
||||
authdat = 0;
|
||||
(void) strcpy(errbuf, "Read req failed: ");
|
||||
(void) strcat(errbuf, error_message(r));
|
||||
Data(ap, KRB_REJECT, errbuf, -1);
|
||||
if (auth_debug_mode)
|
||||
printf("%s\r\n", errbuf);
|
||||
return;
|
||||
}
|
||||
free(name);
|
||||
if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
|
||||
/* do ap_rep stuff here */
|
||||
reply.ctime = authdat->authenticator->ctime;
|
||||
reply.cusec = authdat->authenticator->cusec;
|
||||
reply.subkey = 0; /* use the one he gave us, so don't
|
||||
need to return one here */
|
||||
reply.seq_number = 0; /* we don't do seq #'s. */
|
||||
|
||||
if (r = krb5_mk_rep(&reply,
|
||||
authdat->authenticator->subkey ?
|
||||
authdat->authenticator->subkey :
|
||||
authdat->ticket->enc_part2->session,
|
||||
&outbuf)) {
|
||||
goto errout;
|
||||
}
|
||||
Data(ap, KRB_RESPONSE, outbuf.data, outbuf.length);
|
||||
}
|
||||
if (krb5_unparse_name(authdat->ticket->enc_part2 ->client,
|
||||
&name))
|
||||
name = 0;
|
||||
Data(ap, KRB_ACCEPT, name, name ? -1 : 0);
|
||||
if (auth_debug_mode) {
|
||||
printf("Kerberos5 identifies him as ``%s''\r\n",
|
||||
name ? name : "");
|
||||
}
|
||||
auth_finished(ap, AUTH_USER);
|
||||
|
||||
free(name);
|
||||
if (authdat->authenticator->subkey &&
|
||||
authdat->authenticator->subkey->keytype == KEYTYPE_DES) {
|
||||
memmove((Voidptr )session_key,
|
||||
(Voidptr )authdat->authenticator->subkey->contents,
|
||||
sizeof(Block));
|
||||
} else if (authdat->ticket->enc_part2->session->keytype ==
|
||||
KEYTYPE_DES) {
|
||||
memmove((Voidptr )session_key,
|
||||
(Voidptr )authdat->ticket->enc_part2->session->contents,
|
||||
sizeof(Block));
|
||||
} else
|
||||
break;
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
skey.type = SK_DES;
|
||||
skey.length = 8;
|
||||
skey.data = session_key;
|
||||
encrypt_session_key(&skey, 1);
|
||||
#endif /* ENCRYPTION */
|
||||
break;
|
||||
#ifdef FORWARD
|
||||
case KRB_FORWARD:
|
||||
inbuf.data = (char *)data;
|
||||
inbuf.length = cnt;
|
||||
if (r = rd_and_store_for_creds(&inbuf, authdat->ticket,
|
||||
UserNameRequested)) {
|
||||
char errbuf[128];
|
||||
|
||||
(void) strcpy(errbuf, "Read forwarded creds failed: ");
|
||||
(void) strcat(errbuf, error_message(r));
|
||||
Data(ap, KRB_FORWARD_REJECT, errbuf, -1);
|
||||
if (auth_debug_mode)
|
||||
printf("Could not read forwarded credentials\r\n");
|
||||
}
|
||||
else
|
||||
Data(ap, KRB_FORWARD_ACCEPT, 0, 0);
|
||||
if (auth_debug_mode)
|
||||
printf("Forwarded credentials obtained\r\n");
|
||||
break;
|
||||
#endif /* FORWARD */
|
||||
default:
|
||||
if (auth_debug_mode)
|
||||
printf("Unknown Kerberos option %d\r\n", data[-1]);
|
||||
Data(ap, KRB_REJECT, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kerberos5_reply(ap, data, cnt)
|
||||
Authenticator *ap;
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
Session_Key skey;
|
||||
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:
|
||||
if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
|
||||
!mutual_complete) {
|
||||
printf("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\n");
|
||||
auth_send_retry();
|
||||
return;
|
||||
}
|
||||
if (cnt)
|
||||
printf("[ Kerberos V5 accepts you as ``%.*s'' ]\n", cnt, data);
|
||||
else
|
||||
printf("[ Kerberos V5 accepts you ]\n");
|
||||
auth_finished(ap, AUTH_USER);
|
||||
#ifdef FORWARD
|
||||
if (forward_flags & OPTS_FORWARD_CREDS)
|
||||
kerberos5_forward(ap);
|
||||
#endif /* FORWARD */
|
||||
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 r;
|
||||
krb5_keyblock tmpkey;
|
||||
|
||||
inbuf.length = cnt;
|
||||
inbuf.data = (char *)data;
|
||||
|
||||
tmpkey.keytype = KEYTYPE_DES;
|
||||
tmpkey.contents = session_key;
|
||||
tmpkey.length = sizeof(Block);
|
||||
|
||||
if (r = krb5_rd_rep(&inbuf, &tmpkey, &reply)) {
|
||||
printf("[ Mutual authentication failed: %s ]\n",
|
||||
error_message(r));
|
||||
auth_send_retry();
|
||||
return;
|
||||
}
|
||||
if (reply->ctime != authenticator.ctime ||
|
||||
reply->cusec != authenticator.cusec) {
|
||||
printf("[ Mutual authentication failed (mismatched KRB_AP_REP) ]\n");
|
||||
auth_send_retry();
|
||||
return;
|
||||
}
|
||||
krb5_free_ap_rep_enc_part(reply);
|
||||
#ifdef ENCRYPTION
|
||||
skey.type = SK_DES;
|
||||
skey.length = 8;
|
||||
skey.data = session_key;
|
||||
encrypt_session_key(&skey, 0);
|
||||
#endif /* ENCRYPTION */
|
||||
mutual_complete = 1;
|
||||
}
|
||||
return;
|
||||
#ifdef FORWARD
|
||||
case KRB_FORWARD_ACCEPT:
|
||||
printf("[ Kerberos V5 accepted forwarded credentials ]\n");
|
||||
return;
|
||||
case KRB_FORWARD_REJECT:
|
||||
printf("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n",
|
||||
cnt, data);
|
||||
return;
|
||||
#endif /* FORWARD */
|
||||
default:
|
||||
if (auth_debug_mode)
|
||||
printf("Unknown Kerberos option %d\r\n", data[-1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
kerberos5_status(ap, name, level)
|
||||
Authenticator *ap;
|
||||
char *name;
|
||||
int level;
|
||||
{
|
||||
if (level < AUTH_USER)
|
||||
return(level);
|
||||
|
||||
if (UserNameRequested &&
|
||||
krb5_kuserok(authdat->ticket->enc_part2->client, UserNameRequested))
|
||||
{
|
||||
strcpy(name, UserNameRequested);
|
||||
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(data, cnt, buf, buflen)
|
||||
unsigned char *data, *buf;
|
||||
int cnt, buflen;
|
||||
{
|
||||
char lbuf[32];
|
||||
register int i;
|
||||
|
||||
buf[buflen-1] = '\0'; /* make sure its NULL terminated */
|
||||
buflen -= 1;
|
||||
|
||||
switch(data[3]) {
|
||||
case KRB_REJECT: /* Rejected (reason might follow) */
|
||||
strncpy((char *)buf, " REJECT ", buflen);
|
||||
goto common;
|
||||
|
||||
case KRB_ACCEPT: /* Accepted (name might follow) */
|
||||
strncpy((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 */
|
||||
strncpy((char *)buf, " AUTH", buflen);
|
||||
goto common2;
|
||||
|
||||
case KRB_RESPONSE:
|
||||
strncpy((char *)buf, " RESPONSE", buflen);
|
||||
goto common2;
|
||||
|
||||
#ifdef FORWARD
|
||||
case KRB_FORWARD: /* Forwarded credentials follow */
|
||||
strncpy((char *)buf, " FORWARD", buflen);
|
||||
goto common2;
|
||||
|
||||
case KRB_FORWARD_ACCEPT: /* Forwarded credentials accepted */
|
||||
strncpy((char *)buf, " FORWARD_ACCEPT", buflen);
|
||||
goto common2;
|
||||
|
||||
case KRB_FORWARD_REJECT: /* Forwarded credentials rejected */
|
||||
/* (reason might follow) */
|
||||
strncpy((char *)buf, " FORWARD_REJECT", buflen);
|
||||
goto common2;
|
||||
#endif /* FORWARD */
|
||||
|
||||
default:
|
||||
sprintf(lbuf, " %d (unknown)", data[3]);
|
||||
strncpy((char *)buf, lbuf, buflen);
|
||||
common2:
|
||||
BUMP(buf, buflen);
|
||||
for (i = 4; i < cnt; i++) {
|
||||
sprintf(lbuf, " %d", data[i]);
|
||||
strncpy((char *)buf, lbuf, buflen);
|
||||
BUMP(buf, buflen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FORWARD
|
||||
void
|
||||
kerberos5_forward(ap)
|
||||
Authenticator *ap;
|
||||
{
|
||||
struct hostent *hp;
|
||||
krb5_creds *local_creds;
|
||||
krb5_error_code r;
|
||||
krb5_data forw_creds;
|
||||
extern krb5_cksumtype krb5_kdc_req_sumtype;
|
||||
krb5_ccache ccache;
|
||||
int i;
|
||||
|
||||
if (!(local_creds = (krb5_creds *)
|
||||
calloc(1, sizeof(*local_creds)))) {
|
||||
if (auth_debug_mode)
|
||||
printf("Kerberos V5: could not allocate memory for credentials\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (r = krb5_sname_to_principal(RemoteHostName, "host", 1,
|
||||
&local_creds->server)) {
|
||||
if (auth_debug_mode)
|
||||
printf("Kerberos V5: could not build server name - %s\r\n",
|
||||
error_message(r));
|
||||
krb5_free_creds(local_creds);
|
||||
return;
|
||||
}
|
||||
|
||||
if (r = krb5_cc_default(&ccache)) {
|
||||
if (auth_debug_mode)
|
||||
printf("Kerberos V5: could not get default ccache - %s\r\n",
|
||||
error_message(r));
|
||||
krb5_free_creds(local_creds);
|
||||
return;
|
||||
}
|
||||
|
||||
if (r = krb5_cc_get_principal(ccache, &local_creds->client)) {
|
||||
if (auth_debug_mode)
|
||||
printf("Kerberos V5: could not get default principal - %s\r\n",
|
||||
error_message(r));
|
||||
krb5_free_creds(local_creds);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get ticket from credentials cache */
|
||||
if (r = krb5_get_credentials(KRB5_GC_CACHED, ccache, local_creds)) {
|
||||
if (auth_debug_mode)
|
||||
printf("Kerberos V5: could not obtain credentials - %s\r\n",
|
||||
error_message(r));
|
||||
krb5_free_creds(local_creds);
|
||||
return;
|
||||
}
|
||||
|
||||
if (r = get_for_creds(ETYPE_DES_CBC_CRC,
|
||||
krb5_kdc_req_sumtype,
|
||||
RemoteHostName,
|
||||
local_creds->client,
|
||||
&local_creds->keyblock,
|
||||
forward_flags & OPTS_FORWARDABLE_CREDS,
|
||||
&forw_creds)) {
|
||||
if (auth_debug_mode)
|
||||
printf("Kerberos V5: error getting forwarded creds - %s\r\n",
|
||||
error_message(r));
|
||||
krb5_free_creds(local_creds);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send forwarded credentials */
|
||||
if (!Data(ap, KRB_FORWARD, forw_creds.data, forw_creds.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");
|
||||
}
|
||||
|
||||
krb5_free_creds(local_creds);
|
||||
}
|
||||
#endif /* FORWARD */
|
||||
|
||||
#endif /* KRB5 */
|
71
contrib/telnet/libtelnet/key-proto.h
Normal file
71
contrib/telnet/libtelnet/key-proto.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)key-proto.h 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __KEY_PROTO__
|
||||
#define __KEY_PROTO__
|
||||
|
||||
#if !defined(P)
|
||||
#ifdef __STDC__
|
||||
#define P(x) x
|
||||
#else
|
||||
#define P(x) ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int key_file_exists P((void));
|
||||
void key_lookup P((unsigned char *, Block));
|
||||
void key_stream_init P((Block, Block, int));
|
||||
unsigned char key_stream P((int, int));
|
||||
#endif
|
446
contrib/telnet/libtelnet/krb4encpwd.c
Normal file
446
contrib/telnet/libtelnet/krb4encpwd.c
Normal file
@ -0,0 +1,446 @@
|
||||
/*-
|
||||
* Copyright (c) 1992, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)krb4encpwd.c 8.3 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
#ifdef KRB4_ENCPWD
|
||||
/*
|
||||
* COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
|
||||
* ALL RIGHTS RESERVED
|
||||
*
|
||||
* "Digital Equipment Corporation authorizes the reproduction,
|
||||
* distribution and modification of this software subject to the following
|
||||
* restrictions:
|
||||
*
|
||||
* 1. Any partial or whole copy of this software, or any modification
|
||||
* thereof, must include this copyright notice in its entirety.
|
||||
*
|
||||
* 2. This software is supplied "as is" with no warranty of any kind,
|
||||
* expressed or implied, for any purpose, including any warranty of fitness
|
||||
* or merchantibility. DIGITAL assumes no responsibility for the use or
|
||||
* reliability of this software, nor promises to provide any form of
|
||||
* support for it on any basis.
|
||||
*
|
||||
* 3. Distribution of this software is authorized only if no profit or
|
||||
* remuneration of any kind is received in exchange for such distribution.
|
||||
*
|
||||
* 4. This software produces public key authentication certificates
|
||||
* bearing an expiration date established by DIGITAL and RSA Data
|
||||
* Security, Inc. It may cease to generate certificates after the expiration
|
||||
* date. Any modification of this software that changes or defeats
|
||||
* the expiration date or its effect is unauthorized.
|
||||
*
|
||||
* 5. Software that will renew or extend the expiration date of
|
||||
* authentication certificates produced by this software may be obtained
|
||||
* from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
|
||||
* 94065, (415)595-8782, or from DIGITAL"
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <arpa/telnet.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <des.h>
|
||||
#include <krb.h>
|
||||
#ifdef __STDC__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef NO_STRING_H
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "encrypt.h"
|
||||
#include "auth.h"
|
||||
#include "misc.h"
|
||||
|
||||
int krb_mk_encpwd_req P((KTEXT, char *, char *, char *, char *, char *, char *));
|
||||
int krb_rd_encpwd_req P((KTEXT, char *, char *, u_long, AUTH_DAT *, char *, char *, char *, char *));
|
||||
|
||||
extern auth_debug_mode;
|
||||
|
||||
static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
|
||||
AUTHTYPE_KRB4_ENCPWD, };
|
||||
static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
|
||||
TELQUAL_NAME, };
|
||||
|
||||
#define KRB4_ENCPWD_AUTH 0 /* Authentication data follows */
|
||||
#define KRB4_ENCPWD_REJECT 1 /* Rejected (reason might follow) */
|
||||
#define KRB4_ENCPWD_ACCEPT 2 /* Accepted */
|
||||
#define KRB4_ENCPWD_CHALLENGE 3 /* Challenge for mutual auth. */
|
||||
#define KRB4_ENCPWD_ACK 4 /* Acknowledge */
|
||||
|
||||
#define KRB_SERVICE_NAME "rcmd"
|
||||
|
||||
static KTEXT_ST auth;
|
||||
static char name[ANAME_SZ];
|
||||
static char user_passwd[ANAME_SZ];
|
||||
static AUTH_DAT adat = { 0 };
|
||||
#ifdef ENCRYPTION
|
||||
static Block session_key = { 0 };
|
||||
#endif /* ENCRYPTION */
|
||||
static Schedule sched;
|
||||
static char challenge[REALM_SZ];
|
||||
|
||||
static int
|
||||
Data(ap, type, d, c)
|
||||
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((char *)cd);
|
||||
|
||||
if (0) {
|
||||
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(net_write(str_data, p - str_data));
|
||||
}
|
||||
|
||||
int
|
||||
krb4encpwd_init(ap, server)
|
||||
Authenticator *ap;
|
||||
int server;
|
||||
{
|
||||
char hostname[80], *cp, *realm;
|
||||
C_Block skey;
|
||||
|
||||
if (server) {
|
||||
str_data[3] = TELQUAL_REPLY;
|
||||
} else {
|
||||
str_data[3] = TELQUAL_IS;
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
realm = krb_realmofhost(hostname);
|
||||
cp = strchr(hostname, '.');
|
||||
if (*cp != NULL) *cp = NULL;
|
||||
if (read_service_key(KRB_SERVICE_NAME, hostname, realm, 0,
|
||||
KEYFILE, (char *)skey)) {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
krb4encpwd_send(ap)
|
||||
Authenticator *ap;
|
||||
{
|
||||
|
||||
printf("[ Trying KRB4ENCPWD ... ]\n");
|
||||
if (!UserNameRequested) {
|
||||
return(0);
|
||||
}
|
||||
if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (!Data(ap, KRB4_ENCPWD_ACK, (void *)NULL, 0)) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
void
|
||||
krb4encpwd_is(ap, data, cnt)
|
||||
Authenticator *ap;
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
Session_Key skey;
|
||||
Block datablock;
|
||||
char r_passwd[ANAME_SZ], r_user[ANAME_SZ];
|
||||
char lhostname[ANAME_SZ], *cp;
|
||||
int r;
|
||||
time_t now;
|
||||
|
||||
if (cnt-- < 1)
|
||||
return;
|
||||
switch (*data++) {
|
||||
case KRB4_ENCPWD_AUTH:
|
||||
memmove((void *)auth.dat, (void *)data, auth.length = cnt);
|
||||
|
||||
gethostname(lhostname, sizeof(lhostname));
|
||||
if ((cp = strchr(lhostname, '.')) != 0) *cp = '\0';
|
||||
|
||||
if (r = krb_rd_encpwd_req(&auth, KRB_SERVICE_NAME, lhostname, 0, &adat, NULL, challenge, r_user, r_passwd)) {
|
||||
Data(ap, KRB4_ENCPWD_REJECT, (void *)"Auth failed", -1);
|
||||
auth_finished(ap, AUTH_REJECT);
|
||||
return;
|
||||
}
|
||||
auth_encrypt_userpwd(r_passwd);
|
||||
if (passwdok(UserNameRequested, UserPassword) == 0) {
|
||||
/*
|
||||
* illegal username and password
|
||||
*/
|
||||
Data(ap, KRB4_ENCPWD_REJECT, (void *)"Illegal password", -1);
|
||||
auth_finished(ap, AUTH_REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
memmove((void *)session_key, (void *)adat.session, sizeof(Block));
|
||||
Data(ap, KRB4_ENCPWD_ACCEPT, (void *)0, 0);
|
||||
auth_finished(ap, AUTH_USER);
|
||||
break;
|
||||
|
||||
case KRB4_ENCPWD_CHALLENGE:
|
||||
/*
|
||||
* Take the received random challenge text and save
|
||||
* for future authentication.
|
||||
*/
|
||||
memmove((void *)challenge, (void *)data, sizeof(Block));
|
||||
break;
|
||||
|
||||
|
||||
case KRB4_ENCPWD_ACK:
|
||||
/*
|
||||
* Receive ack, if mutual then send random challenge
|
||||
*/
|
||||
|
||||
/*
|
||||
* If we are doing mutual authentication, get set up to send
|
||||
* the challenge, and verify it when the response comes back.
|
||||
*/
|
||||
|
||||
if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
|
||||
register int i;
|
||||
|
||||
time(&now);
|
||||
sprintf(challenge, "%x", now);
|
||||
Data(ap, KRB4_ENCPWD_CHALLENGE, (void *)challenge, strlen(challenge));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Data(ap, KRB4_ENCPWD_REJECT, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
krb4encpwd_reply(ap, data, cnt)
|
||||
Authenticator *ap;
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
Session_Key skey;
|
||||
KTEXT_ST krb_token;
|
||||
Block enckey;
|
||||
CREDENTIALS cred;
|
||||
int r;
|
||||
char randchal[REALM_SZ], instance[ANAME_SZ], *cp;
|
||||
char hostname[80], *realm;
|
||||
|
||||
if (cnt-- < 1)
|
||||
return;
|
||||
switch (*data++) {
|
||||
case KRB4_ENCPWD_REJECT:
|
||||
if (cnt > 0) {
|
||||
printf("[ KRB4_ENCPWD refuses authentication because %.*s ]\r\n",
|
||||
cnt, data);
|
||||
} else
|
||||
printf("[ KRB4_ENCPWD refuses authentication ]\r\n");
|
||||
auth_send_retry();
|
||||
return;
|
||||
case KRB4_ENCPWD_ACCEPT:
|
||||
printf("[ KRB4_ENCPWD accepts you ]\n");
|
||||
auth_finished(ap, AUTH_USER);
|
||||
return;
|
||||
case KRB4_ENCPWD_CHALLENGE:
|
||||
/*
|
||||
* Verify that the response to the challenge is correct.
|
||||
*/
|
||||
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
realm = krb_realmofhost(hostname);
|
||||
memmove((void *)challenge, (void *)data, cnt);
|
||||
memset(user_passwd, 0, sizeof(user_passwd));
|
||||
local_des_read_pw_string(user_passwd, sizeof(user_passwd)-1, "Password: ", 0);
|
||||
UserPassword = user_passwd;
|
||||
Challenge = challenge;
|
||||
strcpy(instance, RemoteHostName);
|
||||
if ((cp = strchr(instance, '.')) != 0) *cp = '\0';
|
||||
|
||||
if (r = krb_mk_encpwd_req(&krb_token, KRB_SERVICE_NAME, instance, realm, Challenge, UserNameRequested, user_passwd)) {
|
||||
krb_token.length = 0;
|
||||
}
|
||||
|
||||
if (!Data(ap, KRB4_ENCPWD_AUTH, (void *)krb_token.dat, krb_token.length)) {
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
krb4encpwd_status(ap, name, level)
|
||||
Authenticator *ap;
|
||||
char *name;
|
||||
int level;
|
||||
{
|
||||
|
||||
if (level < AUTH_USER)
|
||||
return(level);
|
||||
|
||||
if (UserNameRequested && passwdok(UserNameRequested, UserPassword)) {
|
||||
strcpy(name, UserNameRequested);
|
||||
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
|
||||
krb4encpwd_printsub(data, cnt, buf, buflen)
|
||||
unsigned char *data, *buf;
|
||||
int cnt, buflen;
|
||||
{
|
||||
char lbuf[32];
|
||||
register int i;
|
||||
|
||||
buf[buflen-1] = '\0'; /* make sure its NULL terminated */
|
||||
buflen -= 1;
|
||||
|
||||
switch(data[3]) {
|
||||
case KRB4_ENCPWD_REJECT: /* Rejected (reason might follow) */
|
||||
strncpy((char *)buf, " REJECT ", buflen);
|
||||
goto common;
|
||||
|
||||
case KRB4_ENCPWD_ACCEPT: /* Accepted (name might follow) */
|
||||
strncpy((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 KRB4_ENCPWD_AUTH: /* Authentication data follows */
|
||||
strncpy((char *)buf, " AUTH", buflen);
|
||||
goto common2;
|
||||
|
||||
case KRB4_ENCPWD_CHALLENGE:
|
||||
strncpy((char *)buf, " CHALLENGE", buflen);
|
||||
goto common2;
|
||||
|
||||
case KRB4_ENCPWD_ACK:
|
||||
strncpy((char *)buf, " ACK", buflen);
|
||||
goto common2;
|
||||
|
||||
default:
|
||||
sprintf(lbuf, " %d (unknown)", data[3]);
|
||||
strncpy((char *)buf, lbuf, buflen);
|
||||
common2:
|
||||
BUMP(buf, buflen);
|
||||
for (i = 4; i < cnt; i++) {
|
||||
sprintf(lbuf, " %d", data[i]);
|
||||
strncpy((char *)buf, lbuf, buflen);
|
||||
BUMP(buf, buflen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int passwdok(name, passwd)
|
||||
char *name, *passwd;
|
||||
{
|
||||
char *crypt();
|
||||
char *salt, *p;
|
||||
struct passwd *pwd;
|
||||
int passwdok_status = 0;
|
||||
|
||||
if (pwd = getpwnam(name))
|
||||
salt = pwd->pw_passwd;
|
||||
else salt = "xx";
|
||||
|
||||
p = crypt(passwd, salt);
|
||||
|
||||
if (pwd && !strcmp(p, pwd->pw_passwd)) {
|
||||
passwdok_status = 1;
|
||||
} else passwdok_status = 0;
|
||||
return(passwdok_status);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef notdef
|
||||
|
||||
prkey(msg, key)
|
||||
char *msg;
|
||||
unsigned char *key;
|
||||
{
|
||||
register int i;
|
||||
printf("%s:", msg);
|
||||
for (i = 0; i < 8; i++)
|
||||
printf(" %3d", key[i]);
|
||||
printf("\r\n");
|
||||
}
|
||||
#endif
|
79
contrib/telnet/libtelnet/misc-proto.h
Normal file
79
contrib/telnet/libtelnet/misc-proto.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)misc-proto.h 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __MISC_PROTO__
|
||||
#define __MISC_PROTO__
|
||||
|
||||
#if !defined(P)
|
||||
#ifdef __STDC__
|
||||
#define P(x) x
|
||||
#else
|
||||
#define P(x) ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void auth_encrypt_init P((char *, char *, char *, int));
|
||||
void auth_encrypt_connect P((int));
|
||||
void printd P((unsigned char *, int));
|
||||
|
||||
/*
|
||||
* These functions are imported from the application
|
||||
*/
|
||||
int net_write P((unsigned char *, int));
|
||||
void net_encrypt P((void));
|
||||
int telnet_spin P((void));
|
||||
char *telnet_getenv P((char *));
|
||||
char *telnet_gets P((char *, char *, int, int));
|
||||
#endif
|
94
contrib/telnet/libtelnet/misc.c
Normal file
94
contrib/telnet/libtelnet/misc.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
char *RemoteHostName;
|
||||
char *LocalHostName;
|
||||
char *UserNameRequested = 0;
|
||||
int ConnectedCount = 0;
|
||||
|
||||
void
|
||||
auth_encrypt_init(local, remote, name, server)
|
||||
char *local;
|
||||
char *remote;
|
||||
char *name;
|
||||
int server;
|
||||
{
|
||||
RemoteHostName = remote;
|
||||
LocalHostName = local;
|
||||
#if defined(AUTHENTICATION)
|
||||
auth_init(name, server);
|
||||
#endif
|
||||
#ifdef ENCRYPTION
|
||||
encrypt_init(name, server);
|
||||
#endif /* ENCRYPTION */
|
||||
if (UserNameRequested) {
|
||||
free(UserNameRequested);
|
||||
UserNameRequested = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
auth_encrypt_user(name)
|
||||
char *name;
|
||||
{
|
||||
extern char *strdup();
|
||||
|
||||
if (UserNameRequested)
|
||||
free(UserNameRequested);
|
||||
UserNameRequested = name ? strdup(name) : 0;
|
||||
}
|
||||
|
||||
void
|
||||
auth_encrypt_connect(cnt)
|
||||
int cnt;
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
printd(data, cnt)
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
if (cnt > 16)
|
||||
cnt = 16;
|
||||
while (cnt-- > 0) {
|
||||
printf(" %02x", *data);
|
||||
++data;
|
||||
}
|
||||
}
|
42
contrib/telnet/libtelnet/misc.h
Normal file
42
contrib/telnet/libtelnet/misc.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)misc.h 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
|
||||
extern char *UserNameRequested;
|
||||
extern char *LocalHostName;
|
||||
extern char *RemoteHostName;
|
||||
extern int ConnectedCount;
|
||||
extern int ReservedPort;
|
||||
|
||||
#include "misc-proto.h"
|
145
contrib/telnet/libtelnet/read_password.c
Normal file
145
contrib/telnet/libtelnet/read_password.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*-
|
||||
* Copyright (c) 1992, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)read_password.c 8.3 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* $Source: /mit/kerberos/src/lib/des/RCS/read_password.c,v $
|
||||
* $Author: jon $
|
||||
*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <mit-copyright.h>.
|
||||
*
|
||||
* This routine prints the supplied string to standard
|
||||
* output as a prompt, and reads a password string without
|
||||
* echoing.
|
||||
*/
|
||||
|
||||
#if defined(RSA_ENCPWD) || defined(KRB4_ENCPWD)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
static jmp_buf env;
|
||||
|
||||
/*** Routines ****************************************************** */
|
||||
/*
|
||||
* This version just returns the string, doesn't map to key.
|
||||
*
|
||||
* Returns 0 on success, non-zero on failure.
|
||||
*/
|
||||
|
||||
int
|
||||
local_des_read_pw_string(s,max,prompt,verify)
|
||||
char *s;
|
||||
int max;
|
||||
char *prompt;
|
||||
int verify;
|
||||
{
|
||||
int ok = 0;
|
||||
char *ptr;
|
||||
|
||||
jmp_buf old_env;
|
||||
struct sgttyb tty_state;
|
||||
char key_string[BUFSIZ];
|
||||
|
||||
if (max > BUFSIZ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* XXX assume jmp_buf is typedef'ed to an array */
|
||||
memmove((char *)env, (char *)old_env, sizeof(env));
|
||||
if (setjmp(env))
|
||||
goto lose;
|
||||
|
||||
/* save terminal state*/
|
||||
if (ioctl(0,TIOCGETP,(char *)&tty_state) == -1)
|
||||
return -1;
|
||||
/*
|
||||
push_signals();
|
||||
*/
|
||||
/* Turn off echo */
|
||||
tty_state.sg_flags &= ~ECHO;
|
||||
if (ioctl(0,TIOCSETP,(char *)&tty_state) == -1)
|
||||
return -1;
|
||||
while (!ok) {
|
||||
(void) printf(prompt);
|
||||
(void) fflush(stdout);
|
||||
while (!fgets(s, max, stdin));
|
||||
|
||||
if ((ptr = strchr(s, '\n')))
|
||||
*ptr = '\0';
|
||||
if (verify) {
|
||||
printf("\nVerifying, please re-enter %s",prompt);
|
||||
(void) fflush(stdout);
|
||||
if (!fgets(key_string, sizeof(key_string), stdin)) {
|
||||
clearerr(stdin);
|
||||
continue;
|
||||
}
|
||||
if ((ptr = strchr(key_string, '\n')))
|
||||
*ptr = '\0';
|
||||
if (strcmp(s,key_string)) {
|
||||
printf("\n\07\07Mismatch - try again\n");
|
||||
(void) fflush(stdout);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ok = 1;
|
||||
}
|
||||
|
||||
lose:
|
||||
if (!ok)
|
||||
memset(s, 0, max);
|
||||
printf("\n");
|
||||
/* turn echo back on */
|
||||
tty_state.sg_flags |= ECHO;
|
||||
if (ioctl(0,TIOCSETP,(char *)&tty_state))
|
||||
ok = 0;
|
||||
/*
|
||||
pop_signals();
|
||||
*/
|
||||
memmove((char *)old_env, (char *)env, sizeof(env));
|
||||
if (verify)
|
||||
memset(key_string, 0, sizeof (key_string));
|
||||
s[max-1] = 0; /* force termination */
|
||||
return !ok; /* return nonzero if not okay */
|
||||
}
|
||||
#endif /* defined(RSA_ENCPWD) || defined(KRB4_ENCPWD) */
|
492
contrib/telnet/libtelnet/rsaencpwd.c
Normal file
492
contrib/telnet/libtelnet/rsaencpwd.c
Normal file
@ -0,0 +1,492 @@
|
||||
/*-
|
||||
* Copyright (c) 1992, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)rsaencpwd.c 8.3 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
#ifdef RSA_ENCPWD
|
||||
/*
|
||||
* COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
|
||||
* ALL RIGHTS RESERVED
|
||||
*
|
||||
* "Digital Equipment Corporation authorizes the reproduction,
|
||||
* distribution and modification of this software subject to the following
|
||||
* restrictions:
|
||||
*
|
||||
* 1. Any partial or whole copy of this software, or any modification
|
||||
* thereof, must include this copyright notice in its entirety.
|
||||
*
|
||||
* 2. This software is supplied "as is" with no warranty of any kind,
|
||||
* expressed or implied, for any purpose, including any warranty of fitness
|
||||
* or merchantibility. DIGITAL assumes no responsibility for the use or
|
||||
* reliability of this software, nor promises to provide any form of
|
||||
* support for it on any basis.
|
||||
*
|
||||
* 3. Distribution of this software is authorized only if no profit or
|
||||
* remuneration of any kind is received in exchange for such distribution.
|
||||
*
|
||||
* 4. This software produces public key authentication certificates
|
||||
* bearing an expiration date established by DIGITAL and RSA Data
|
||||
* Security, Inc. It may cease to generate certificates after the expiration
|
||||
* date. Any modification of this software that changes or defeats
|
||||
* the expiration date or its effect is unauthorized.
|
||||
*
|
||||
* 5. Software that will renew or extend the expiration date of
|
||||
* authentication certificates produced by this software may be obtained
|
||||
* from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
|
||||
* 94065, (415)595-8782, or from DIGITAL"
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <arpa/telnet.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __STDC__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef NO_STRING_H
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "encrypt.h"
|
||||
#include "auth.h"
|
||||
#include "misc.h"
|
||||
#include "cdc.h"
|
||||
|
||||
extern auth_debug_mode;
|
||||
|
||||
static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
|
||||
AUTHTYPE_RSA_ENCPWD, };
|
||||
static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
|
||||
TELQUAL_NAME, };
|
||||
|
||||
#define RSA_ENCPWD_AUTH 0 /* Authentication data follows */
|
||||
#define RSA_ENCPWD_REJECT 1 /* Rejected (reason might follow) */
|
||||
#define RSA_ENCPWD_ACCEPT 2 /* Accepted */
|
||||
#define RSA_ENCPWD_CHALLENGEKEY 3 /* Challenge and public key */
|
||||
|
||||
#define NAME_SZ 40
|
||||
#define CHAL_SZ 20
|
||||
#define PWD_SZ 40
|
||||
|
||||
static KTEXT_ST auth;
|
||||
static char name[NAME_SZ];
|
||||
static char user_passwd[PWD_SZ];
|
||||
static char key_file[2*NAME_SZ];
|
||||
static char lhostname[NAME_SZ];
|
||||
static char challenge[CHAL_SZ];
|
||||
static int challenge_len;
|
||||
|
||||
static int
|
||||
Data(ap, type, d, c)
|
||||
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((char *)cd);
|
||||
|
||||
if (0) {
|
||||
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;
|
||||
if (type != NULL) *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(net_write(str_data, p - str_data));
|
||||
}
|
||||
|
||||
int
|
||||
rsaencpwd_init(ap, server)
|
||||
Authenticator *ap;
|
||||
int server;
|
||||
{
|
||||
char *cp;
|
||||
FILE *fp;
|
||||
|
||||
if (server) {
|
||||
str_data[3] = TELQUAL_REPLY;
|
||||
memset(key_file, 0, sizeof(key_file));
|
||||
gethostname(lhostname, sizeof(lhostname));
|
||||
if ((cp = strchr(lhostname, '.')) != 0) *cp = '\0';
|
||||
strcpy(key_file, "/etc/.");
|
||||
strcat(key_file, lhostname);
|
||||
strcat(key_file, "_privkey");
|
||||
if ((fp=fopen(key_file, "r"))==NULL) return(0);
|
||||
fclose(fp);
|
||||
} else {
|
||||
str_data[3] = TELQUAL_IS;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
rsaencpwd_send(ap)
|
||||
Authenticator *ap;
|
||||
{
|
||||
|
||||
printf("[ Trying RSAENCPWD ... ]\n");
|
||||
if (!UserNameRequested) {
|
||||
return(0);
|
||||
}
|
||||
if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
|
||||
return(0);
|
||||
}
|
||||
if (!Data(ap, NULL, (void *)NULL, 0)) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
void
|
||||
rsaencpwd_is(ap, data, cnt)
|
||||
Authenticator *ap;
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
Session_Key skey;
|
||||
Block datablock;
|
||||
char r_passwd[PWD_SZ], r_user[NAME_SZ];
|
||||
char *cp, key[160];
|
||||
char chalkey[160], *ptr;
|
||||
FILE *fp;
|
||||
int r, i, j, chalkey_len, len;
|
||||
time_t now;
|
||||
|
||||
cnt--;
|
||||
switch (*data++) {
|
||||
case RSA_ENCPWD_AUTH:
|
||||
memmove((void *)auth.dat, (void *)data, auth.length = cnt);
|
||||
|
||||
if ((fp=fopen(key_file, "r"))==NULL) {
|
||||
Data(ap, RSA_ENCPWD_REJECT, (void *)"Auth failed", -1);
|
||||
auth_finished(ap, AUTH_REJECT);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* get privkey
|
||||
*/
|
||||
fscanf(fp, "%x;", &len);
|
||||
for (i=0;i<len;i++) {
|
||||
j = getc(fp); key[i]=j;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
r = accept_rsa_encpwd(&auth, key, challenge,
|
||||
challenge_len, r_passwd);
|
||||
if (r < 0) {
|
||||
Data(ap, RSA_ENCPWD_REJECT, (void *)"Auth failed", -1);
|
||||
auth_finished(ap, AUTH_REJECT);
|
||||
return;
|
||||
}
|
||||
auth_encrypt_userpwd(r_passwd);
|
||||
if (rsaencpwd_passwdok(UserNameRequested, UserPassword) == 0) {
|
||||
/*
|
||||
* illegal username and password
|
||||
*/
|
||||
Data(ap, RSA_ENCPWD_REJECT, (void *)"Illegal password", -1);
|
||||
auth_finished(ap, AUTH_REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
Data(ap, RSA_ENCPWD_ACCEPT, (void *)0, 0);
|
||||
auth_finished(ap, AUTH_USER);
|
||||
break;
|
||||
|
||||
|
||||
case IAC:
|
||||
|
||||
/*
|
||||
* If we are doing mutual authentication, get set up to send
|
||||
* the challenge, and verify it when the response comes back.
|
||||
*/
|
||||
if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY) {
|
||||
register int i;
|
||||
|
||||
|
||||
time(&now);
|
||||
if ((now % 2) == 0) {
|
||||
sprintf(challenge, "%x", now);
|
||||
challenge_len = strlen(challenge);
|
||||
} else {
|
||||
strcpy(challenge, "randchal");
|
||||
challenge_len = 8;
|
||||
}
|
||||
|
||||
if ((fp=fopen(key_file, "r"))==NULL) {
|
||||
Data(ap, RSA_ENCPWD_REJECT, (void *)"Auth failed", -1);
|
||||
auth_finished(ap, AUTH_REJECT);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* skip privkey
|
||||
*/
|
||||
fscanf(fp, "%x;", &len);
|
||||
for (i=0;i<len;i++) {
|
||||
j = getc(fp);
|
||||
}
|
||||
/*
|
||||
* get pubkey
|
||||
*/
|
||||
fscanf(fp, "%x;", &len);
|
||||
for (i=0;i<len;i++) {
|
||||
j = getc(fp); key[i]=j;
|
||||
}
|
||||
fclose(fp);
|
||||
chalkey[0] = 0x30;
|
||||
ptr = (char *) &chalkey[1];
|
||||
chalkey_len = 1+NumEncodeLengthOctets(i)+i+1+NumEncodeLengthOctets(challenge_len)+challenge_len;
|
||||
EncodeLength(ptr, chalkey_len);
|
||||
ptr +=NumEncodeLengthOctets(chalkey_len);
|
||||
*ptr++ = 0x04; /* OCTET STRING */
|
||||
*ptr++ = challenge_len;
|
||||
memmove(ptr, challenge, challenge_len);
|
||||
ptr += challenge_len;
|
||||
*ptr++ = 0x04; /* OCTET STRING */
|
||||
EncodeLength(ptr, i);
|
||||
ptr += NumEncodeLengthOctets(i);
|
||||
memmove(ptr, key, i);
|
||||
chalkey_len = 1+NumEncodeLengthOctets(chalkey_len)+chalkey_len;
|
||||
Data(ap, RSA_ENCPWD_CHALLENGEKEY, (void *)chalkey, chalkey_len);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Data(ap, RSA_ENCPWD_REJECT, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rsaencpwd_reply(ap, data, cnt)
|
||||
Authenticator *ap;
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
Session_Key skey;
|
||||
KTEXT_ST token;
|
||||
Block enckey;
|
||||
int r, pubkey_len;
|
||||
char randchal[CHAL_SZ], *cp;
|
||||
char chalkey[160], pubkey[128], *ptr;
|
||||
|
||||
if (cnt-- < 1)
|
||||
return;
|
||||
switch (*data++) {
|
||||
case RSA_ENCPWD_REJECT:
|
||||
if (cnt > 0) {
|
||||
printf("[ RSA_ENCPWD refuses authentication because %.*s ]\r\n",
|
||||
cnt, data);
|
||||
} else
|
||||
printf("[ RSA_ENCPWD refuses authentication ]\r\n");
|
||||
auth_send_retry();
|
||||
return;
|
||||
case RSA_ENCPWD_ACCEPT:
|
||||
printf("[ RSA_ENCPWD accepts you ]\n");
|
||||
auth_finished(ap, AUTH_USER);
|
||||
return;
|
||||
case RSA_ENCPWD_CHALLENGEKEY:
|
||||
/*
|
||||
* Verify that the response to the challenge is correct.
|
||||
*/
|
||||
|
||||
memmove((void *)chalkey, (void *)data, cnt);
|
||||
ptr = (char *) &chalkey[0];
|
||||
ptr += DecodeHeaderLength(chalkey);
|
||||
if (*ptr != 0x04) {
|
||||
return;
|
||||
}
|
||||
*ptr++;
|
||||
challenge_len = DecodeValueLength(ptr);
|
||||
ptr += NumEncodeLengthOctets(challenge_len);
|
||||
memmove(challenge, ptr, challenge_len);
|
||||
ptr += challenge_len;
|
||||
if (*ptr != 0x04) {
|
||||
return;
|
||||
}
|
||||
*ptr++;
|
||||
pubkey_len = DecodeValueLength(ptr);
|
||||
ptr += NumEncodeLengthOctets(pubkey_len);
|
||||
memmove(pubkey, ptr, pubkey_len);
|
||||
memset(user_passwd, 0, sizeof(user_passwd));
|
||||
local_des_read_pw_string(user_passwd, sizeof(user_passwd)-1, "Password: ", 0);
|
||||
UserPassword = user_passwd;
|
||||
Challenge = challenge;
|
||||
r = init_rsa_encpwd(&token, user_passwd, challenge, challenge_len, pubkey);
|
||||
if (r < 0) {
|
||||
token.length = 1;
|
||||
}
|
||||
|
||||
if (!Data(ap, RSA_ENCPWD_AUTH, (void *)token.dat, token.length)) {
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rsaencpwd_status(ap, name, level)
|
||||
Authenticator *ap;
|
||||
char *name;
|
||||
int level;
|
||||
{
|
||||
|
||||
if (level < AUTH_USER)
|
||||
return(level);
|
||||
|
||||
if (UserNameRequested && rsaencpwd_passwdok(UserNameRequested, UserPassword)) {
|
||||
strcpy(name, UserNameRequested);
|
||||
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
|
||||
rsaencpwd_printsub(data, cnt, buf, buflen)
|
||||
unsigned char *data, *buf;
|
||||
int cnt, buflen;
|
||||
{
|
||||
char lbuf[32];
|
||||
register int i;
|
||||
|
||||
buf[buflen-1] = '\0'; /* make sure its NULL terminated */
|
||||
buflen -= 1;
|
||||
|
||||
switch(data[3]) {
|
||||
case RSA_ENCPWD_REJECT: /* Rejected (reason might follow) */
|
||||
strncpy((char *)buf, " REJECT ", buflen);
|
||||
goto common;
|
||||
|
||||
case RSA_ENCPWD_ACCEPT: /* Accepted (name might follow) */
|
||||
strncpy((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 RSA_ENCPWD_AUTH: /* Authentication data follows */
|
||||
strncpy((char *)buf, " AUTH", buflen);
|
||||
goto common2;
|
||||
|
||||
case RSA_ENCPWD_CHALLENGEKEY:
|
||||
strncpy((char *)buf, " CHALLENGEKEY", buflen);
|
||||
goto common2;
|
||||
|
||||
default:
|
||||
sprintf(lbuf, " %d (unknown)", data[3]);
|
||||
strncpy((char *)buf, lbuf, buflen);
|
||||
common2:
|
||||
BUMP(buf, buflen);
|
||||
for (i = 4; i < cnt; i++) {
|
||||
sprintf(lbuf, " %d", data[i]);
|
||||
strncpy((char *)buf, lbuf, buflen);
|
||||
BUMP(buf, buflen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int rsaencpwd_passwdok(name, passwd)
|
||||
char *name, *passwd;
|
||||
{
|
||||
char *crypt();
|
||||
char *salt, *p;
|
||||
struct passwd *pwd;
|
||||
int passwdok_status = 0;
|
||||
|
||||
if (pwd = getpwnam(name))
|
||||
salt = pwd->pw_passwd;
|
||||
else salt = "xx";
|
||||
|
||||
p = crypt(passwd, salt);
|
||||
|
||||
if (pwd && !strcmp(p, pwd->pw_passwd)) {
|
||||
passwdok_status = 1;
|
||||
} else passwdok_status = 0;
|
||||
return(passwdok_status);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef notdef
|
||||
|
||||
prkey(msg, key)
|
||||
char *msg;
|
||||
unsigned char *key;
|
||||
{
|
||||
register int i;
|
||||
printf("%s:", msg);
|
||||
for (i = 0; i < 8; i++)
|
||||
printf(" %3d", key[i]);
|
||||
printf("\r\n");
|
||||
}
|
||||
#endif
|
588
contrib/telnet/libtelnet/spx.c
Normal file
588
contrib/telnet/libtelnet/spx.c
Normal file
@ -0,0 +1,588 @@
|
||||
/*-
|
||||
* Copyright (c) 1992, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)spx.c 8.2 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef SPX
|
||||
/*
|
||||
* COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
|
||||
* ALL RIGHTS RESERVED
|
||||
*
|
||||
* "Digital Equipment Corporation authorizes the reproduction,
|
||||
* distribution and modification of this software subject to the following
|
||||
* restrictions:
|
||||
*
|
||||
* 1. Any partial or whole copy of this software, or any modification
|
||||
* thereof, must include this copyright notice in its entirety.
|
||||
*
|
||||
* 2. This software is supplied "as is" with no warranty of any kind,
|
||||
* expressed or implied, for any purpose, including any warranty of fitness
|
||||
* or merchantibility. DIGITAL assumes no responsibility for the use or
|
||||
* reliability of this software, nor promises to provide any form of
|
||||
* support for it on any basis.
|
||||
*
|
||||
* 3. Distribution of this software is authorized only if no profit or
|
||||
* remuneration of any kind is received in exchange for such distribution.
|
||||
*
|
||||
* 4. This software produces public key authentication certificates
|
||||
* bearing an expiration date established by DIGITAL and RSA Data
|
||||
* Security, Inc. It may cease to generate certificates after the expiration
|
||||
* date. Any modification of this software that changes or defeats
|
||||
* the expiration date or its effect is unauthorized.
|
||||
*
|
||||
* 5. Software that will renew or extend the expiration date of
|
||||
* authentication certificates produced by this software may be obtained
|
||||
* from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
|
||||
* 94065, (415)595-8782, or from DIGITAL"
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <arpa/telnet.h>
|
||||
#include <stdio.h>
|
||||
#include "gssapi_defs.h"
|
||||
#ifdef __STDC__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef NO_STRING_H
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <pwd.h>
|
||||
#include "encrypt.h"
|
||||
#include "auth.h"
|
||||
#include "misc.h"
|
||||
|
||||
extern auth_debug_mode;
|
||||
|
||||
static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
|
||||
AUTHTYPE_SPX, };
|
||||
static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
|
||||
TELQUAL_NAME, };
|
||||
|
||||
#define SPX_AUTH 0 /* Authentication data follows */
|
||||
#define SPX_REJECT 1 /* Rejected (reason might follow) */
|
||||
#define SPX_ACCEPT 2 /* Accepted */
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
static Block session_key = { 0 };
|
||||
#endif /* ENCRYPTION */
|
||||
static Schedule sched;
|
||||
static Block challenge = { 0 };
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
gss_OID_set actual_mechs;
|
||||
gss_OID actual_mech_type, output_name_type;
|
||||
int major_status, status, msg_ctx = 0, new_status;
|
||||
int req_flags = 0, ret_flags, lifetime_rec;
|
||||
gss_cred_id_t gss_cred_handle;
|
||||
gss_ctx_id_t actual_ctxhandle, context_handle;
|
||||
gss_buffer_desc output_token, input_token, input_name_buffer;
|
||||
gss_buffer_desc status_string;
|
||||
gss_name_t desired_targname, src_name;
|
||||
gss_channel_bindings input_chan_bindings;
|
||||
char lhostname[GSS_C_MAX_PRINTABLE_NAME];
|
||||
char targ_printable[GSS_C_MAX_PRINTABLE_NAME];
|
||||
int to_addr=0, from_addr=0;
|
||||
char *address;
|
||||
gss_buffer_desc fullname_buffer;
|
||||
gss_OID fullname_type;
|
||||
gss_cred_id_t gss_delegated_cred_handle;
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
|
||||
static int
|
||||
Data(ap, type, d, c)
|
||||
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((char *)cd);
|
||||
|
||||
if (0) {
|
||||
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(net_write(str_data, p - str_data));
|
||||
}
|
||||
|
||||
int
|
||||
spx_init(ap, server)
|
||||
Authenticator *ap;
|
||||
int server;
|
||||
{
|
||||
gss_cred_id_t tmp_cred_handle;
|
||||
|
||||
if (server) {
|
||||
str_data[3] = TELQUAL_REPLY;
|
||||
gethostname(lhostname, sizeof(lhostname));
|
||||
strcpy(targ_printable, "SERVICE:rcmd@");
|
||||
strcat(targ_printable, lhostname);
|
||||
input_name_buffer.length = strlen(targ_printable);
|
||||
input_name_buffer.value = targ_printable;
|
||||
major_status = gss_import_name(&status,
|
||||
&input_name_buffer,
|
||||
GSS_C_NULL_OID,
|
||||
&desired_targname);
|
||||
major_status = gss_acquire_cred(&status,
|
||||
desired_targname,
|
||||
0,
|
||||
GSS_C_NULL_OID_SET,
|
||||
GSS_C_ACCEPT,
|
||||
&tmp_cred_handle,
|
||||
&actual_mechs,
|
||||
&lifetime_rec);
|
||||
if (major_status != GSS_S_COMPLETE) return(0);
|
||||
} else {
|
||||
str_data[3] = TELQUAL_IS;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
spx_send(ap)
|
||||
Authenticator *ap;
|
||||
{
|
||||
Block enckey;
|
||||
int r;
|
||||
|
||||
gss_OID actual_mech_type, output_name_type;
|
||||
int msg_ctx = 0, new_status, status;
|
||||
int req_flags = 0, ret_flags, lifetime_rec, major_status;
|
||||
gss_buffer_desc output_token, input_token, input_name_buffer;
|
||||
gss_buffer_desc output_name_buffer, status_string;
|
||||
gss_name_t desired_targname;
|
||||
gss_channel_bindings input_chan_bindings;
|
||||
char targ_printable[GSS_C_MAX_PRINTABLE_NAME];
|
||||
int from_addr=0, to_addr=0, myhostlen, j;
|
||||
int deleg_flag=1, mutual_flag=0, replay_flag=0, seq_flag=0;
|
||||
char *address;
|
||||
|
||||
printf("[ Trying SPX ... ]\n");
|
||||
strcpy(targ_printable, "SERVICE:rcmd@");
|
||||
strcat(targ_printable, RemoteHostName);
|
||||
|
||||
input_name_buffer.length = strlen(targ_printable);
|
||||
input_name_buffer.value = targ_printable;
|
||||
|
||||
if (!UserNameRequested) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
major_status = gss_import_name(&status,
|
||||
&input_name_buffer,
|
||||
GSS_C_NULL_OID,
|
||||
&desired_targname);
|
||||
|
||||
|
||||
major_status = gss_display_name(&status,
|
||||
desired_targname,
|
||||
&output_name_buffer,
|
||||
&output_name_type);
|
||||
|
||||
printf("target is '%s'\n", output_name_buffer.value); fflush(stdout);
|
||||
|
||||
major_status = gss_release_buffer(&status, &output_name_buffer);
|
||||
|
||||
input_chan_bindings = (gss_channel_bindings)
|
||||
malloc(sizeof(gss_channel_bindings_desc));
|
||||
|
||||
input_chan_bindings->initiator_addrtype = GSS_C_AF_INET;
|
||||
input_chan_bindings->initiator_address.length = 4;
|
||||
address = (char *) malloc(4);
|
||||
input_chan_bindings->initiator_address.value = (char *) address;
|
||||
address[0] = ((from_addr & 0xff000000) >> 24);
|
||||
address[1] = ((from_addr & 0xff0000) >> 16);
|
||||
address[2] = ((from_addr & 0xff00) >> 8);
|
||||
address[3] = (from_addr & 0xff);
|
||||
input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET;
|
||||
input_chan_bindings->acceptor_address.length = 4;
|
||||
address = (char *) malloc(4);
|
||||
input_chan_bindings->acceptor_address.value = (char *) address;
|
||||
address[0] = ((to_addr & 0xff000000) >> 24);
|
||||
address[1] = ((to_addr & 0xff0000) >> 16);
|
||||
address[2] = ((to_addr & 0xff00) >> 8);
|
||||
address[3] = (to_addr & 0xff);
|
||||
input_chan_bindings->application_data.length = 0;
|
||||
|
||||
req_flags = 0;
|
||||
if (deleg_flag) req_flags = req_flags | 1;
|
||||
if (mutual_flag) req_flags = req_flags | 2;
|
||||
if (replay_flag) req_flags = req_flags | 4;
|
||||
if (seq_flag) req_flags = req_flags | 8;
|
||||
|
||||
major_status = gss_init_sec_context(&status, /* minor status */
|
||||
GSS_C_NO_CREDENTIAL, /* cred handle */
|
||||
&actual_ctxhandle, /* ctx handle */
|
||||
desired_targname, /* target name */
|
||||
GSS_C_NULL_OID, /* mech type */
|
||||
req_flags, /* req flags */
|
||||
0, /* time req */
|
||||
input_chan_bindings, /* chan binding */
|
||||
GSS_C_NO_BUFFER, /* input token */
|
||||
&actual_mech_type, /* actual mech */
|
||||
&output_token, /* output token */
|
||||
&ret_flags, /* ret flags */
|
||||
&lifetime_rec); /* time rec */
|
||||
|
||||
if ((major_status != GSS_S_COMPLETE) &&
|
||||
(major_status != GSS_S_CONTINUE_NEEDED)) {
|
||||
gss_display_status(&new_status,
|
||||
status,
|
||||
GSS_C_MECH_CODE,
|
||||
GSS_C_NULL_OID,
|
||||
&msg_ctx,
|
||||
&status_string);
|
||||
printf("%s\n", status_string.value);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (!Data(ap, SPX_AUTH, (void *)output_token.value, output_token.length)) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
void
|
||||
spx_is(ap, data, cnt)
|
||||
Authenticator *ap;
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
Session_Key skey;
|
||||
Block datablock;
|
||||
int r;
|
||||
|
||||
if (cnt-- < 1)
|
||||
return;
|
||||
switch (*data++) {
|
||||
case SPX_AUTH:
|
||||
input_token.length = cnt;
|
||||
input_token.value = (char *) data;
|
||||
|
||||
gethostname(lhostname, sizeof(lhostname));
|
||||
|
||||
strcpy(targ_printable, "SERVICE:rcmd@");
|
||||
strcat(targ_printable, lhostname);
|
||||
|
||||
input_name_buffer.length = strlen(targ_printable);
|
||||
input_name_buffer.value = targ_printable;
|
||||
|
||||
major_status = gss_import_name(&status,
|
||||
&input_name_buffer,
|
||||
GSS_C_NULL_OID,
|
||||
&desired_targname);
|
||||
|
||||
major_status = gss_acquire_cred(&status,
|
||||
desired_targname,
|
||||
0,
|
||||
GSS_C_NULL_OID_SET,
|
||||
GSS_C_ACCEPT,
|
||||
&gss_cred_handle,
|
||||
&actual_mechs,
|
||||
&lifetime_rec);
|
||||
|
||||
major_status = gss_release_name(&status, desired_targname);
|
||||
|
||||
input_chan_bindings = (gss_channel_bindings)
|
||||
malloc(sizeof(gss_channel_bindings_desc));
|
||||
|
||||
input_chan_bindings->initiator_addrtype = GSS_C_AF_INET;
|
||||
input_chan_bindings->initiator_address.length = 4;
|
||||
address = (char *) malloc(4);
|
||||
input_chan_bindings->initiator_address.value = (char *) address;
|
||||
address[0] = ((from_addr & 0xff000000) >> 24);
|
||||
address[1] = ((from_addr & 0xff0000) >> 16);
|
||||
address[2] = ((from_addr & 0xff00) >> 8);
|
||||
address[3] = (from_addr & 0xff);
|
||||
input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET;
|
||||
input_chan_bindings->acceptor_address.length = 4;
|
||||
address = (char *) malloc(4);
|
||||
input_chan_bindings->acceptor_address.value = (char *) address;
|
||||
address[0] = ((to_addr & 0xff000000) >> 24);
|
||||
address[1] = ((to_addr & 0xff0000) >> 16);
|
||||
address[2] = ((to_addr & 0xff00) >> 8);
|
||||
address[3] = (to_addr & 0xff);
|
||||
input_chan_bindings->application_data.length = 0;
|
||||
|
||||
major_status = gss_accept_sec_context(&status,
|
||||
&context_handle,
|
||||
gss_cred_handle,
|
||||
&input_token,
|
||||
input_chan_bindings,
|
||||
&src_name,
|
||||
&actual_mech_type,
|
||||
&output_token,
|
||||
&ret_flags,
|
||||
&lifetime_rec,
|
||||
&gss_delegated_cred_handle);
|
||||
|
||||
|
||||
if (major_status != GSS_S_COMPLETE) {
|
||||
|
||||
major_status = gss_display_name(&status,
|
||||
src_name,
|
||||
&fullname_buffer,
|
||||
&fullname_type);
|
||||
Data(ap, SPX_REJECT, (void *)"auth failed", -1);
|
||||
auth_finished(ap, AUTH_REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
major_status = gss_display_name(&status,
|
||||
src_name,
|
||||
&fullname_buffer,
|
||||
&fullname_type);
|
||||
|
||||
|
||||
Data(ap, SPX_ACCEPT, (void *)output_token.value, output_token.length);
|
||||
auth_finished(ap, AUTH_USER);
|
||||
break;
|
||||
|
||||
default:
|
||||
Data(ap, SPX_REJECT, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
spx_reply(ap, data, cnt)
|
||||
Authenticator *ap;
|
||||
unsigned char *data;
|
||||
int cnt;
|
||||
{
|
||||
Session_Key skey;
|
||||
|
||||
if (cnt-- < 1)
|
||||
return;
|
||||
switch (*data++) {
|
||||
case SPX_REJECT:
|
||||
if (cnt > 0) {
|
||||
printf("[ SPX refuses authentication because %.*s ]\r\n",
|
||||
cnt, data);
|
||||
} else
|
||||
printf("[ SPX refuses authentication ]\r\n");
|
||||
auth_send_retry();
|
||||
return;
|
||||
case SPX_ACCEPT:
|
||||
printf("[ SPX accepts you ]\n");
|
||||
if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
|
||||
/*
|
||||
* Send over the encrypted challenge.
|
||||
*/
|
||||
input_token.value = (char *) data;
|
||||
input_token.length = cnt;
|
||||
|
||||
major_status = gss_init_sec_context(&status, /* minor stat */
|
||||
GSS_C_NO_CREDENTIAL, /* cred handle */
|
||||
&actual_ctxhandle, /* ctx handle */
|
||||
desired_targname, /* target name */
|
||||
GSS_C_NULL_OID, /* mech type */
|
||||
req_flags, /* req flags */
|
||||
0, /* time req */
|
||||
input_chan_bindings, /* chan binding */
|
||||
&input_token, /* input token */
|
||||
&actual_mech_type, /* actual mech */
|
||||
&output_token, /* output token */
|
||||
&ret_flags, /* ret flags */
|
||||
&lifetime_rec); /* time rec */
|
||||
|
||||
if (major_status != GSS_S_COMPLETE) {
|
||||
gss_display_status(&new_status,
|
||||
status,
|
||||
GSS_C_MECH_CODE,
|
||||
GSS_C_NULL_OID,
|
||||
&msg_ctx,
|
||||
&status_string);
|
||||
printf("[ SPX mutual response fails ... '%s' ]\r\n",
|
||||
status_string.value);
|
||||
auth_send_retry();
|
||||
return;
|
||||
}
|
||||
}
|
||||
auth_finished(ap, AUTH_USER);
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
spx_status(ap, name, level)
|
||||
Authenticator *ap;
|
||||
char *name;
|
||||
int level;
|
||||
{
|
||||
|
||||
gss_buffer_desc fullname_buffer, acl_file_buffer;
|
||||
gss_OID fullname_type;
|
||||
char acl_file[160], fullname[160];
|
||||
int major_status, status = 0;
|
||||
struct passwd *pwd;
|
||||
|
||||
/*
|
||||
* hard code fullname to
|
||||
* "SPX:/C=US/O=Digital/OU=LKG/OU=Sphinx/OU=Users/CN=Kannan Alagappan"
|
||||
* and acl_file to "~kannan/.sphinx"
|
||||
*/
|
||||
|
||||
pwd = getpwnam(UserNameRequested);
|
||||
if (pwd == NULL) {
|
||||
return(AUTH_USER); /* not authenticated */
|
||||
}
|
||||
|
||||
strcpy(acl_file, pwd->pw_dir);
|
||||
strcat(acl_file, "/.sphinx");
|
||||
acl_file_buffer.value = acl_file;
|
||||
acl_file_buffer.length = strlen(acl_file);
|
||||
|
||||
major_status = gss_display_name(&status,
|
||||
src_name,
|
||||
&fullname_buffer,
|
||||
&fullname_type);
|
||||
|
||||
if (level < AUTH_USER)
|
||||
return(level);
|
||||
|
||||
major_status = gss__check_acl(&status, &fullname_buffer,
|
||||
&acl_file_buffer);
|
||||
|
||||
if (major_status == GSS_S_COMPLETE) {
|
||||
strcpy(name, UserNameRequested);
|
||||
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
|
||||
spx_printsub(data, cnt, buf, buflen)
|
||||
unsigned char *data, *buf;
|
||||
int cnt, buflen;
|
||||
{
|
||||
char lbuf[32];
|
||||
register int i;
|
||||
|
||||
buf[buflen-1] = '\0'; /* make sure its NULL terminated */
|
||||
buflen -= 1;
|
||||
|
||||
switch(data[3]) {
|
||||
case SPX_REJECT: /* Rejected (reason might follow) */
|
||||
strncpy((char *)buf, " REJECT ", buflen);
|
||||
goto common;
|
||||
|
||||
case SPX_ACCEPT: /* Accepted (name might follow) */
|
||||
strncpy((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 SPX_AUTH: /* Authentication data follows */
|
||||
strncpy((char *)buf, " AUTH", buflen);
|
||||
goto common2;
|
||||
|
||||
default:
|
||||
sprintf(lbuf, " %d (unknown)", data[3]);
|
||||
strncpy((char *)buf, lbuf, buflen);
|
||||
common2:
|
||||
BUMP(buf, buflen);
|
||||
for (i = 4; i < cnt; i++) {
|
||||
sprintf(lbuf, " %d", data[i]);
|
||||
strncpy((char *)buf, lbuf, buflen);
|
||||
BUMP(buf, buflen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef notdef
|
||||
|
||||
prkey(msg, key)
|
||||
char *msg;
|
||||
unsigned char *key;
|
||||
{
|
||||
register int i;
|
||||
printf("%s:", msg);
|
||||
for (i = 0; i < 8; i++)
|
||||
printf(" %3d", key[i]);
|
||||
printf("\r\n");
|
||||
}
|
||||
#endif
|
111
contrib/telnet/telnet/authenc.c
Normal file
111
contrib/telnet/telnet/authenc.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)authenc.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif /* not lint */
|
||||
|
||||
#if defined(AUTHENTICATION) || defined(ENCRYPTION)
|
||||
#include <sys/types.h>
|
||||
#include <arpa/telnet.h>
|
||||
#include <libtelnet/encrypt.h>
|
||||
#include <libtelnet/misc.h>
|
||||
|
||||
#include "general.h"
|
||||
#include "ring.h"
|
||||
#include "externs.h"
|
||||
#include "defines.h"
|
||||
#include "types.h"
|
||||
|
||||
int
|
||||
net_write(str, len)
|
||||
unsigned char *str;
|
||||
int len;
|
||||
{
|
||||
if (NETROOM() > len) {
|
||||
ring_supply_data(&netoring, str, len);
|
||||
if (str[0] == IAC && str[1] == SE)
|
||||
printsub('>', &str[2], len-2);
|
||||
return(len);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
net_encrypt()
|
||||
{
|
||||
#ifdef ENCRYPTION
|
||||
if (encrypt_output)
|
||||
ring_encrypt(&netoring, encrypt_output);
|
||||
else
|
||||
ring_clearto(&netoring);
|
||||
#endif /* ENCRYPTION */
|
||||
}
|
||||
|
||||
int
|
||||
telnet_spin()
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
char *
|
||||
telnet_getenv(val)
|
||||
char *val;
|
||||
{
|
||||
return((char *)env_getvalue((unsigned char *)val));
|
||||
}
|
||||
|
||||
char *
|
||||
telnet_gets(prompt, result, length, echo)
|
||||
char *prompt;
|
||||
char *result;
|
||||
int length;
|
||||
int echo;
|
||||
{
|
||||
extern char *getpass();
|
||||
extern int globalmode;
|
||||
int om = globalmode;
|
||||
char *res;
|
||||
|
||||
TerminalNewMode(-1);
|
||||
if (echo) {
|
||||
printf("%s", prompt);
|
||||
res = fgets(result, length, stdin);
|
||||
} else if (res = getpass(prompt)) {
|
||||
strncpy(result, res, length);
|
||||
res = result;
|
||||
}
|
||||
TerminalNewMode(om);
|
||||
return(res);
|
||||
}
|
||||
#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
|
2945
contrib/telnet/telnet/commands.c
Normal file
2945
contrib/telnet/telnet/commands.c
Normal file
File diff suppressed because it is too large
Load Diff
61
contrib/telnet/telnet/defines.h
Normal file
61
contrib/telnet/telnet/defines.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)defines.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
#define settimer(x) clocks.x = clocks.system++
|
||||
|
||||
#if !defined(TN3270)
|
||||
|
||||
#define SetIn3270()
|
||||
|
||||
#endif /* !defined(TN3270) */
|
||||
|
||||
#define NETADD(c) { *netoring.supply = c; ring_supplied(&netoring, 1); }
|
||||
#define NET2ADD(c1,c2) { NETADD(c1); NETADD(c2); }
|
||||
#define NETBYTES() (ring_full_count(&netoring))
|
||||
#define NETROOM() (ring_empty_count(&netoring))
|
||||
|
||||
#define TTYADD(c) if (!(SYNCHing||flushout)) { \
|
||||
*ttyoring.supply = c; \
|
||||
ring_supplied(&ttyoring, 1); \
|
||||
}
|
||||
#define TTYBYTES() (ring_full_count(&ttyoring))
|
||||
#define TTYROOM() (ring_empty_count(&ttyoring))
|
||||
|
||||
/* Various modes */
|
||||
#define MODE_LOCAL_CHARS(m) ((m)&(MODE_EDIT|MODE_TRAPSIG))
|
||||
#define MODE_LOCAL_ECHO(m) ((m)&MODE_ECHO)
|
||||
#define MODE_COMMAND_LINE(m) ((m)==-1)
|
||||
|
||||
#define CONTROL(x) ((x)&0x1f) /* CTRL(x) is not portable */
|
482
contrib/telnet/telnet/externs.h
Normal file
482
contrib/telnet/telnet/externs.h
Normal file
@ -0,0 +1,482 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1990, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)externs.h 8.3 (Berkeley) 5/30/95
|
||||
*/
|
||||
|
||||
#ifndef BSD
|
||||
# define BSD 43
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ucb stdio.h defines BSD as something wierd
|
||||
*/
|
||||
#if defined(sun) && defined(__svr4__)
|
||||
#define BSD 43
|
||||
#endif
|
||||
|
||||
#ifndef USE_TERMIO
|
||||
# if BSD > 43 || defined(SYSV_TERMIO)
|
||||
# define USE_TERMIO
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#if defined(CRAY) && !defined(NO_BSD_SETJMP)
|
||||
#include <bsdsetjmp.h>
|
||||
#endif
|
||||
#ifndef FILIO_H
|
||||
#include <sys/ioctl.h>
|
||||
#else
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
#ifdef CRAY
|
||||
# include <errno.h>
|
||||
#endif /* CRAY */
|
||||
#ifdef USE_TERMIO
|
||||
# ifndef VINTR
|
||||
# ifdef SYSV_TERMIO
|
||||
# include <sys/termio.h>
|
||||
# else
|
||||
# include <sys/termios.h>
|
||||
# define termio termios
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if defined(NO_CC_T) || !defined(USE_TERMIO)
|
||||
# if !defined(USE_TERMIO)
|
||||
typedef char cc_t;
|
||||
# else
|
||||
typedef unsigned char cc_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef NO_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX_VDISABLE
|
||||
# ifdef sun
|
||||
# include <sys/param.h> /* pick up VDISABLE definition, mayby */
|
||||
# endif
|
||||
# ifdef VDISABLE
|
||||
# define _POSIX_VDISABLE VDISABLE
|
||||
# else
|
||||
# define _POSIX_VDISABLE ((cc_t)'\377')
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define SUBBUFSIZE 256
|
||||
|
||||
#ifndef CRAY
|
||||
extern int errno; /* outside this world */
|
||||
#endif /* !CRAY */
|
||||
|
||||
#if !defined(P)
|
||||
# ifdef __STDC__
|
||||
# define P(x) x
|
||||
# else
|
||||
# define P(x) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
extern int
|
||||
autologin, /* Autologin enabled */
|
||||
skiprc, /* Don't process the ~/.telnetrc file */
|
||||
eight, /* use eight bit mode (binary in and/or out */
|
||||
flushout, /* flush output */
|
||||
connected, /* Are we connected to the other side? */
|
||||
globalmode, /* Mode tty should be in */
|
||||
In3270, /* Are we in 3270 mode? */
|
||||
telnetport, /* Are we connected to the telnet port? */
|
||||
localflow, /* Flow control handled locally */
|
||||
restartany, /* If flow control, restart output on any character */
|
||||
localchars, /* we recognize interrupt/quit */
|
||||
donelclchars, /* the user has set "localchars" */
|
||||
showoptions,
|
||||
net, /* Network file descriptor */
|
||||
tin, /* Terminal input file descriptor */
|
||||
tout, /* Terminal output file descriptor */
|
||||
crlf, /* Should '\r' be mapped to <CR><LF> (or <CR><NUL>)? */
|
||||
autoflush, /* flush output when interrupting? */
|
||||
autosynch, /* send interrupt characters with SYNCH? */
|
||||
SYNCHing, /* Is the stream in telnet SYNCH mode? */
|
||||
donebinarytoggle, /* the user has put us in binary */
|
||||
dontlecho, /* do we suppress local echoing right now? */
|
||||
crmod,
|
||||
netdata, /* Print out network data flow */
|
||||
prettydump, /* Print "netdata" output in user readable format */
|
||||
#if defined(unix)
|
||||
#if defined(TN3270)
|
||||
cursesdata, /* Print out curses data flow */
|
||||
apitrace, /* Trace API transactions */
|
||||
#endif /* defined(TN3270) */
|
||||
termdata, /* Print out terminal data flow */
|
||||
#endif /* defined(unix) */
|
||||
debug; /* Debug level */
|
||||
|
||||
extern cc_t escape; /* Escape to command mode */
|
||||
extern cc_t rlogin; /* Rlogin mode escape character */
|
||||
#ifdef KLUDGELINEMODE
|
||||
extern cc_t echoc; /* Toggle local echoing */
|
||||
#endif
|
||||
|
||||
extern char
|
||||
*prompt; /* Prompt for command. */
|
||||
|
||||
extern char
|
||||
doopt[],
|
||||
dont[],
|
||||
will[],
|
||||
wont[],
|
||||
options[], /* All the little options */
|
||||
*hostname; /* Who are we connected to? */
|
||||
#ifdef ENCRYPTION
|
||||
extern void (*encrypt_output) P((unsigned char *, int));
|
||||
extern int (*decrypt_input) P((int));
|
||||
#endif /* ENCRYPTION */
|
||||
|
||||
/*
|
||||
* 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;}
|
||||
|
||||
/*
|
||||
* Make everything symetrical
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
|
||||
extern FILE
|
||||
*NetTrace; /* Where debugging output goes */
|
||||
extern unsigned char
|
||||
NetTraceFile[]; /* Name of file where debugging output goes */
|
||||
extern void
|
||||
SetNetTrace P((char *)); /* Function to change where debugging goes */
|
||||
|
||||
extern jmp_buf
|
||||
peerdied,
|
||||
toplevel; /* For error conditions. */
|
||||
|
||||
extern void
|
||||
command P((int, char *, int)),
|
||||
Dump P((int, unsigned char *, int)),
|
||||
init_3270 P((void)),
|
||||
printoption P((char *, int, int)),
|
||||
printsub P((int, unsigned char *, int)),
|
||||
sendnaws P((void)),
|
||||
setconnmode P((int)),
|
||||
setcommandmode P((void)),
|
||||
setneturg P((void)),
|
||||
sys_telnet_init P((void)),
|
||||
telnet P((char *)),
|
||||
tel_enter_binary P((int)),
|
||||
TerminalFlushOutput P((void)),
|
||||
TerminalNewMode P((int)),
|
||||
TerminalRestoreState P((void)),
|
||||
TerminalSaveState P((void)),
|
||||
tninit P((void)),
|
||||
upcase P((char *)),
|
||||
willoption P((int)),
|
||||
wontoption P((int));
|
||||
|
||||
extern void
|
||||
send_do P((int, int)),
|
||||
send_dont P((int, int)),
|
||||
send_will P((int, int)),
|
||||
send_wont P((int, int));
|
||||
|
||||
extern void
|
||||
lm_will P((unsigned char *, int)),
|
||||
lm_wont P((unsigned char *, int)),
|
||||
lm_do P((unsigned char *, int)),
|
||||
lm_dont P((unsigned char *, int)),
|
||||
lm_mode P((unsigned char *, int, int));
|
||||
|
||||
extern void
|
||||
slc_init P((void)),
|
||||
slcstate P((void)),
|
||||
slc_mode_export P((void)),
|
||||
slc_mode_import P((int)),
|
||||
slc_import P((int)),
|
||||
slc_export P((void)),
|
||||
slc P((unsigned char *, int)),
|
||||
slc_check P((void)),
|
||||
slc_start_reply P((void)),
|
||||
slc_add_reply P((int, int, int)),
|
||||
slc_end_reply P((void));
|
||||
extern int
|
||||
slc_update P((void));
|
||||
|
||||
extern void
|
||||
env_opt P((unsigned char *, int)),
|
||||
env_opt_start P((void)),
|
||||
env_opt_start_info P((void)),
|
||||
env_opt_add P((unsigned char *)),
|
||||
env_opt_end P((int));
|
||||
|
||||
extern unsigned char
|
||||
*env_default P((int, int)),
|
||||
*env_getvalue P((unsigned char *));
|
||||
|
||||
extern int
|
||||
get_status P((void)),
|
||||
dosynch P((void));
|
||||
|
||||
extern cc_t
|
||||
*tcval P((int));
|
||||
|
||||
#ifndef USE_TERMIO
|
||||
|
||||
extern struct tchars ntc;
|
||||
extern struct ltchars nltc;
|
||||
extern struct sgttyb nttyb;
|
||||
|
||||
# define termEofChar ntc.t_eofc
|
||||
# define termEraseChar nttyb.sg_erase
|
||||
# define termFlushChar nltc.t_flushc
|
||||
# define termIntChar ntc.t_intrc
|
||||
# define termKillChar nttyb.sg_kill
|
||||
# define termLiteralNextChar nltc.t_lnextc
|
||||
# define termQuitChar ntc.t_quitc
|
||||
# define termSuspChar nltc.t_suspc
|
||||
# define termRprntChar nltc.t_rprntc
|
||||
# define termWerasChar nltc.t_werasc
|
||||
# define termStartChar ntc.t_startc
|
||||
# define termStopChar ntc.t_stopc
|
||||
# define termForw1Char ntc.t_brkc
|
||||
extern cc_t termForw2Char;
|
||||
extern cc_t termAytChar;
|
||||
|
||||
# define termEofCharp (cc_t *)&ntc.t_eofc
|
||||
# define termEraseCharp (cc_t *)&nttyb.sg_erase
|
||||
# define termFlushCharp (cc_t *)&nltc.t_flushc
|
||||
# define termIntCharp (cc_t *)&ntc.t_intrc
|
||||
# define termKillCharp (cc_t *)&nttyb.sg_kill
|
||||
# define termLiteralNextCharp (cc_t *)&nltc.t_lnextc
|
||||
# define termQuitCharp (cc_t *)&ntc.t_quitc
|
||||
# define termSuspCharp (cc_t *)&nltc.t_suspc
|
||||
# define termRprntCharp (cc_t *)&nltc.t_rprntc
|
||||
# define termWerasCharp (cc_t *)&nltc.t_werasc
|
||||
# define termStartCharp (cc_t *)&ntc.t_startc
|
||||
# define termStopCharp (cc_t *)&ntc.t_stopc
|
||||
# define termForw1Charp (cc_t *)&ntc.t_brkc
|
||||
# define termForw2Charp (cc_t *)&termForw2Char
|
||||
# define termAytCharp (cc_t *)&termAytChar
|
||||
|
||||
# else
|
||||
|
||||
extern struct termio new_tc;
|
||||
|
||||
# define termEofChar new_tc.c_cc[VEOF]
|
||||
# define termEraseChar new_tc.c_cc[VERASE]
|
||||
# define termIntChar new_tc.c_cc[VINTR]
|
||||
# define termKillChar new_tc.c_cc[VKILL]
|
||||
# define termQuitChar new_tc.c_cc[VQUIT]
|
||||
|
||||
# ifndef VSUSP
|
||||
extern cc_t termSuspChar;
|
||||
# else
|
||||
# define termSuspChar new_tc.c_cc[VSUSP]
|
||||
# endif
|
||||
# if defined(VFLUSHO) && !defined(VDISCARD)
|
||||
# define VDISCARD VFLUSHO
|
||||
# endif
|
||||
# ifndef VDISCARD
|
||||
extern cc_t termFlushChar;
|
||||
# else
|
||||
# define termFlushChar new_tc.c_cc[VDISCARD]
|
||||
# endif
|
||||
# ifndef VWERASE
|
||||
extern cc_t termWerasChar;
|
||||
# else
|
||||
# define termWerasChar new_tc.c_cc[VWERASE]
|
||||
# endif
|
||||
# ifndef VREPRINT
|
||||
extern cc_t termRprntChar;
|
||||
# else
|
||||
# define termRprntChar new_tc.c_cc[VREPRINT]
|
||||
# endif
|
||||
# ifndef VLNEXT
|
||||
extern cc_t termLiteralNextChar;
|
||||
# else
|
||||
# define termLiteralNextChar new_tc.c_cc[VLNEXT]
|
||||
# endif
|
||||
# ifndef VSTART
|
||||
extern cc_t termStartChar;
|
||||
# else
|
||||
# define termStartChar new_tc.c_cc[VSTART]
|
||||
# endif
|
||||
# ifndef VSTOP
|
||||
extern cc_t termStopChar;
|
||||
# else
|
||||
# define termStopChar new_tc.c_cc[VSTOP]
|
||||
# endif
|
||||
# ifndef VEOL
|
||||
extern cc_t termForw1Char;
|
||||
# else
|
||||
# define termForw1Char new_tc.c_cc[VEOL]
|
||||
# endif
|
||||
# ifndef VEOL2
|
||||
extern cc_t termForw2Char;
|
||||
# else
|
||||
# define termForw2Char new_tc.c_cc[VEOL]
|
||||
# endif
|
||||
# ifndef VSTATUS
|
||||
extern cc_t termAytChar;
|
||||
#else
|
||||
# define termAytChar new_tc.c_cc[VSTATUS]
|
||||
#endif
|
||||
|
||||
# if !defined(CRAY) || defined(__STDC__)
|
||||
# define termEofCharp &termEofChar
|
||||
# define termEraseCharp &termEraseChar
|
||||
# define termIntCharp &termIntChar
|
||||
# define termKillCharp &termKillChar
|
||||
# define termQuitCharp &termQuitChar
|
||||
# define termSuspCharp &termSuspChar
|
||||
# define termFlushCharp &termFlushChar
|
||||
# define termWerasCharp &termWerasChar
|
||||
# define termRprntCharp &termRprntChar
|
||||
# define termLiteralNextCharp &termLiteralNextChar
|
||||
# define termStartCharp &termStartChar
|
||||
# define termStopCharp &termStopChar
|
||||
# define termForw1Charp &termForw1Char
|
||||
# define termForw2Charp &termForw2Char
|
||||
# define termAytCharp &termAytChar
|
||||
# else
|
||||
/* Work around a compiler bug */
|
||||
# define termEofCharp 0
|
||||
# define termEraseCharp 0
|
||||
# define termIntCharp 0
|
||||
# define termKillCharp 0
|
||||
# define termQuitCharp 0
|
||||
# define termSuspCharp 0
|
||||
# define termFlushCharp 0
|
||||
# define termWerasCharp 0
|
||||
# define termRprntCharp 0
|
||||
# define termLiteralNextCharp 0
|
||||
# define termStartCharp 0
|
||||
# define termStopCharp 0
|
||||
# define termForw1Charp 0
|
||||
# define termForw2Charp 0
|
||||
# define termAytCharp 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Ring buffer structures which are shared */
|
||||
|
||||
extern Ring
|
||||
netoring,
|
||||
netiring,
|
||||
ttyoring,
|
||||
ttyiring;
|
||||
|
||||
/* Tn3270 section */
|
||||
#if defined(TN3270)
|
||||
|
||||
extern int
|
||||
HaveInput, /* Whether an asynchronous I/O indication came in */
|
||||
noasynchtty, /* Don't do signals on I/O (SIGURG, SIGIO) */
|
||||
noasynchnet, /* Don't do signals on I/O (SIGURG, SIGIO) */
|
||||
sigiocount, /* Count of SIGIO receptions */
|
||||
shell_active; /* Subshell is active */
|
||||
|
||||
extern char
|
||||
*Ibackp, /* Oldest byte of 3270 data */
|
||||
Ibuf[], /* 3270 buffer */
|
||||
*Ifrontp, /* Where next 3270 byte goes */
|
||||
tline[],
|
||||
*transcom; /* Transparent command */
|
||||
|
||||
extern int
|
||||
settranscom P((int, char**));
|
||||
|
||||
extern void
|
||||
inputAvailable P((int));
|
||||
#endif /* defined(TN3270) */
|
49
contrib/telnet/telnet/fdset.h
Normal file
49
contrib/telnet/telnet/fdset.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)fdset.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following is defined just in case someone should want to run
|
||||
* this telnet on a 4.2 system.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FD_SETSIZE
|
||||
|
||||
#define FD_SET(n, p) ((p)->fds_bits[0] |= (1<<(n)))
|
||||
#define FD_CLR(n, p) ((p)->fds_bits[0] &= ~(1<<(n)))
|
||||
#define FD_ISSET(n, p) ((p)->fds_bits[0] & (1<<(n)))
|
||||
#define FD_ZERO(p) ((p)->fds_bits[0] = 0)
|
||||
|
||||
#endif
|
45
contrib/telnet/telnet/general.h
Normal file
45
contrib/telnet/telnet/general.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)general.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some general definitions.
|
||||
*/
|
||||
|
||||
|
||||
#define numberof(x) (sizeof x/sizeof x[0])
|
||||
#define highestof(x) (numberof(x)-1)
|
||||
|
||||
#define ClearElement(x) memset((char *)&x, 0, sizeof x)
|
||||
#define ClearArray(x) memset((char *)x, 0, sizeof x)
|
322
contrib/telnet/telnet/main.c
Normal file
322
contrib/telnet/telnet/main.c
Normal file
@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1990, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1988, 1990, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "ring.h"
|
||||
#include "externs.h"
|
||||
#include "defines.h"
|
||||
|
||||
/* These values need to be the same as defined in libtelnet/kerberos5.c */
|
||||
/* Either define them in both places, or put in some common header file. */
|
||||
#define OPTS_FORWARD_CREDS 0x00000002
|
||||
#define OPTS_FORWARDABLE_CREDS 0x00000001
|
||||
|
||||
#if 0
|
||||
#define FORWARD
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize variables.
|
||||
*/
|
||||
void
|
||||
tninit()
|
||||
{
|
||||
init_terminal();
|
||||
|
||||
init_network();
|
||||
|
||||
init_telnet();
|
||||
|
||||
init_sys();
|
||||
|
||||
#if defined(TN3270)
|
||||
init_3270();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "Usage: %s %s%s%s%s\n",
|
||||
prompt,
|
||||
#ifdef AUTHENTICATION
|
||||
"[-8] [-E] [-K] [-L] [-S tos] [-X atype] [-a] [-c] [-d] [-e char]",
|
||||
"\n\t[-k realm] [-l user] [-f/-F] [-n tracefile] ",
|
||||
#else
|
||||
"[-8] [-E] [-L] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
|
||||
"\n\t[-n tracefile]",
|
||||
#endif
|
||||
#if defined(TN3270) && defined(unix)
|
||||
# ifdef AUTHENTICATION
|
||||
"[-noasynch] [-noasynctty]\n\t[-noasyncnet] [-r] [-t transcom] ",
|
||||
# else
|
||||
"[-noasynch] [-noasynctty] [-noasyncnet] [-r]\n\t[-t transcom]",
|
||||
# endif
|
||||
#else
|
||||
"[-r] ",
|
||||
#endif
|
||||
#ifdef ENCRYPTION
|
||||
"[-x] [host-name [port]]"
|
||||
#else /* ENCRYPTION */
|
||||
"[host-name [port]]"
|
||||
#endif /* ENCRYPTION */
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* main. Parse arguments, invoke the protocol or command parser.
|
||||
*/
|
||||
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
int ch;
|
||||
char *user, *strrchr();
|
||||
#ifdef FORWARD
|
||||
extern int forward_flags;
|
||||
#endif /* FORWARD */
|
||||
|
||||
tninit(); /* Clear out things */
|
||||
#if defined(CRAY) && !defined(__STDC__)
|
||||
_setlist_init(); /* Work around compiler bug */
|
||||
#endif
|
||||
|
||||
TerminalSaveState();
|
||||
|
||||
if (prompt = strrchr(argv[0], '/'))
|
||||
++prompt;
|
||||
else
|
||||
prompt = argv[0];
|
||||
|
||||
user = NULL;
|
||||
|
||||
rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
|
||||
autologin = -1;
|
||||
|
||||
while ((ch = getopt(argc, argv, "8EKLS:X:acde:fFk:l:n:rt:x")) != EOF) {
|
||||
switch(ch) {
|
||||
case '8':
|
||||
eight = 3; /* binary output and input */
|
||||
break;
|
||||
case 'E':
|
||||
rlogin = escape = _POSIX_VDISABLE;
|
||||
break;
|
||||
case 'K':
|
||||
#ifdef AUTHENTICATION
|
||||
autologin = 0;
|
||||
#endif
|
||||
break;
|
||||
case 'L':
|
||||
eight |= 2; /* binary output only */
|
||||
break;
|
||||
case 'S':
|
||||
{
|
||||
#ifdef HAS_GETTOS
|
||||
extern int tos;
|
||||
|
||||
if ((tos = parsetos(optarg, "tcp")) < 0)
|
||||
fprintf(stderr, "%s%s%s%s\n",
|
||||
prompt, ": Bad TOS argument '",
|
||||
optarg,
|
||||
"; will try to use default TOS");
|
||||
#else
|
||||
fprintf(stderr,
|
||||
"%s: Warning: -S ignored, no parsetos() support.\n",
|
||||
prompt);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 'X':
|
||||
#ifdef AUTHENTICATION
|
||||
auth_disable_name(optarg);
|
||||
#endif
|
||||
break;
|
||||
case 'a':
|
||||
autologin = 1;
|
||||
break;
|
||||
case 'c':
|
||||
skiprc = 1;
|
||||
break;
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'e':
|
||||
set_escape_char(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
|
||||
if (forward_flags & OPTS_FORWARD_CREDS) {
|
||||
fprintf(stderr,
|
||||
"%s: Only one of -f and -F allowed.\n",
|
||||
prompt);
|
||||
usage();
|
||||
}
|
||||
forward_flags |= OPTS_FORWARD_CREDS;
|
||||
#else
|
||||
fprintf(stderr,
|
||||
"%s: Warning: -f ignored, no Kerberos V5 support.\n",
|
||||
prompt);
|
||||
#endif
|
||||
break;
|
||||
case 'F':
|
||||
#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
|
||||
if (forward_flags & OPTS_FORWARD_CREDS) {
|
||||
fprintf(stderr,
|
||||
"%s: Only one of -f and -F allowed.\n",
|
||||
prompt);
|
||||
usage();
|
||||
}
|
||||
forward_flags |= OPTS_FORWARD_CREDS;
|
||||
forward_flags |= OPTS_FORWARDABLE_CREDS;
|
||||
#else
|
||||
fprintf(stderr,
|
||||
"%s: Warning: -F ignored, no Kerberos V5 support.\n",
|
||||
prompt);
|
||||
#endif
|
||||
break;
|
||||
case 'k':
|
||||
#if defined(AUTHENTICATION) && defined(KRB4)
|
||||
{
|
||||
extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
|
||||
dest_realm = dst_realm_buf;
|
||||
(void)strncpy(dest_realm, optarg, dst_realm_sz);
|
||||
}
|
||||
#else
|
||||
fprintf(stderr,
|
||||
"%s: Warning: -k ignored, no Kerberos V4 support.\n",
|
||||
prompt);
|
||||
#endif
|
||||
break;
|
||||
case 'l':
|
||||
autologin = 1;
|
||||
user = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
#if defined(TN3270) && defined(unix)
|
||||
/* distinguish between "-n oasynch" and "-noasynch" */
|
||||
if (argv[optind - 1][0] == '-' && argv[optind - 1][1]
|
||||
== 'n' && argv[optind - 1][2] == 'o') {
|
||||
if (!strcmp(optarg, "oasynch")) {
|
||||
noasynchtty = 1;
|
||||
noasynchnet = 1;
|
||||
} else if (!strcmp(optarg, "oasynchtty"))
|
||||
noasynchtty = 1;
|
||||
else if (!strcmp(optarg, "oasynchnet"))
|
||||
noasynchnet = 1;
|
||||
} else
|
||||
#endif /* defined(TN3270) && defined(unix) */
|
||||
SetNetTrace(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
rlogin = '~';
|
||||
break;
|
||||
case 't':
|
||||
#if defined(TN3270) && defined(unix)
|
||||
transcom = tline;
|
||||
(void)strcpy(transcom, optarg);
|
||||
#else
|
||||
fprintf(stderr,
|
||||
"%s: Warning: -t ignored, no TN3270 support.\n",
|
||||
prompt);
|
||||
#endif
|
||||
break;
|
||||
case 'x':
|
||||
#ifdef ENCRYPTION
|
||||
encrypt_auto(1);
|
||||
decrypt_auto(1);
|
||||
#else /* ENCRYPTION */
|
||||
fprintf(stderr,
|
||||
"%s: Warning: -x ignored, no ENCRYPT support.\n",
|
||||
prompt);
|
||||
#endif /* ENCRYPTION */
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
if (autologin == -1)
|
||||
autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc) {
|
||||
char *args[7], **argp = args;
|
||||
|
||||
if (argc > 2)
|
||||
usage();
|
||||
*argp++ = prompt;
|
||||
if (user) {
|
||||
*argp++ = "-l";
|
||||
*argp++ = user;
|
||||
}
|
||||
*argp++ = argv[0]; /* host */
|
||||
if (argc > 1)
|
||||
*argp++ = argv[1]; /* port */
|
||||
*argp = 0;
|
||||
|
||||
if (setjmp(toplevel) != 0)
|
||||
Exit(0);
|
||||
if (tn(argp - args, args) == 1)
|
||||
return (0);
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
(void)setjmp(toplevel);
|
||||
for (;;) {
|
||||
#ifdef TN3270
|
||||
if (shell_active)
|
||||
shell_continue();
|
||||
else
|
||||
#endif
|
||||
command(1, 0, 0);
|
||||
}
|
||||
}
|
177
contrib/telnet/telnet/network.c
Normal file
177
contrib/telnet/telnet/network.c
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)network.c 8.2 (Berkeley) 12/15/93";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <arpa/telnet.h>
|
||||
|
||||
#include "ring.h"
|
||||
|
||||
#include "defines.h"
|
||||
#include "externs.h"
|
||||
#include "fdset.h"
|
||||
|
||||
Ring netoring, netiring;
|
||||
unsigned char netobuf[2*BUFSIZ], netibuf[BUFSIZ];
|
||||
|
||||
/*
|
||||
* Initialize internal network data structures.
|
||||
*/
|
||||
|
||||
void
|
||||
init_network()
|
||||
{
|
||||
if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
|
||||
exit(1);
|
||||
}
|
||||
if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
|
||||
exit(1);
|
||||
}
|
||||
NetTrace = stdout;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check to see if any out-of-band data exists on a socket (for
|
||||
* Telnet "synch" processing).
|
||||
*/
|
||||
|
||||
int
|
||||
stilloob()
|
||||
{
|
||||
static struct timeval timeout = { 0 };
|
||||
fd_set excepts;
|
||||
int value;
|
||||
|
||||
do {
|
||||
FD_ZERO(&excepts);
|
||||
FD_SET(net, &excepts);
|
||||
value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
|
||||
} while ((value == -1) && (errno == EINTR));
|
||||
|
||||
if (value < 0) {
|
||||
perror("select");
|
||||
(void) quit();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (FD_ISSET(net, &excepts)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* setneturg()
|
||||
*
|
||||
* Sets "neturg" to the current location.
|
||||
*/
|
||||
|
||||
void
|
||||
setneturg()
|
||||
{
|
||||
ring_mark(&netoring);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* netflush
|
||||
* Send as much data as possible to the network,
|
||||
* handling requests for urgent data.
|
||||
*
|
||||
* The return value indicates whether we did any
|
||||
* useful work.
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
netflush()
|
||||
{
|
||||
register int n, n1;
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
if (encrypt_output)
|
||||
ring_encrypt(&netoring, encrypt_output);
|
||||
#endif /* ENCRYPTION */
|
||||
if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
|
||||
if (!ring_at_mark(&netoring)) {
|
||||
n = send(net, (char *)netoring.consume, n, 0); /* normal write */
|
||||
} else {
|
||||
/*
|
||||
* 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).
|
||||
*/
|
||||
n = send(net, (char *)netoring.consume, 1, MSG_OOB);/* URGENT data */
|
||||
}
|
||||
}
|
||||
if (n < 0) {
|
||||
if (errno != ENOBUFS && errno != EWOULDBLOCK) {
|
||||
setcommandmode();
|
||||
perror(hostname);
|
||||
(void)NetClose(net);
|
||||
ring_clear_mark(&netoring);
|
||||
longjmp(peerdied, -1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
n = 0;
|
||||
}
|
||||
if (netdata && n) {
|
||||
Dump('>', netoring.consume, n);
|
||||
}
|
||||
if (n) {
|
||||
ring_consumed(&netoring, n);
|
||||
/*
|
||||
* If we sent all, and more to send, then recurse to pick
|
||||
* up the other half.
|
||||
*/
|
||||
if ((n1 == n) && ring_full_consecutive(&netoring)) {
|
||||
(void) netflush();
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
362
contrib/telnet/telnet/ring.c
Normal file
362
contrib/telnet/telnet/ring.c
Normal file
@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)ring.c 8.2 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* This defines a structure for a ring buffer.
|
||||
*
|
||||
* The circular buffer has two parts:
|
||||
*(((
|
||||
* full: [consume, supply)
|
||||
* empty: [supply, consume)
|
||||
*]]]
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef size_t
|
||||
#undef size_t
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef FILIO_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "ring.h"
|
||||
#include "general.h"
|
||||
|
||||
/* Internal macros */
|
||||
|
||||
#if !defined(MIN)
|
||||
#define MIN(a,b) (((a)<(b))? (a):(b))
|
||||
#endif /* !defined(MIN) */
|
||||
|
||||
#define ring_subtract(d,a,b) (((a)-(b) >= 0)? \
|
||||
(a)-(b): (((a)-(b))+(d)->size))
|
||||
|
||||
#define ring_increment(d,a,c) (((a)+(c) < (d)->top)? \
|
||||
(a)+(c) : (((a)+(c))-(d)->size))
|
||||
|
||||
#define ring_decrement(d,a,c) (((a)-(c) >= (d)->bottom)? \
|
||||
(a)-(c) : (((a)-(c))-(d)->size))
|
||||
|
||||
|
||||
/*
|
||||
* The following is a clock, used to determine full, empty, etc.
|
||||
*
|
||||
* There is some trickiness here. Since the ring buffers are initialized
|
||||
* to ZERO on allocation, we need to make sure, when interpreting the
|
||||
* clock, that when the times are EQUAL, then the buffer is FULL.
|
||||
*/
|
||||
static u_long ring_clock = 0;
|
||||
|
||||
|
||||
#define ring_empty(d) (((d)->consume == (d)->supply) && \
|
||||
((d)->consumetime >= (d)->supplytime))
|
||||
#define ring_full(d) (((d)->supply == (d)->consume) && \
|
||||
((d)->supplytime > (d)->consumetime))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Buffer state transition routines */
|
||||
|
||||
ring_init(ring, buffer, count)
|
||||
Ring *ring;
|
||||
unsigned char *buffer;
|
||||
int count;
|
||||
{
|
||||
memset((char *)ring, 0, sizeof *ring);
|
||||
|
||||
ring->size = count;
|
||||
|
||||
ring->supply = ring->consume = ring->bottom = buffer;
|
||||
|
||||
ring->top = ring->bottom+ring->size;
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
ring->clearto = 0;
|
||||
#endif /* ENCRYPTION */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Mark routines */
|
||||
|
||||
/*
|
||||
* Mark the most recently supplied byte.
|
||||
*/
|
||||
|
||||
void
|
||||
ring_mark(ring)
|
||||
Ring *ring;
|
||||
{
|
||||
ring->mark = ring_decrement(ring, ring->supply, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the ring pointing to the mark?
|
||||
*/
|
||||
|
||||
int
|
||||
ring_at_mark(ring)
|
||||
Ring *ring;
|
||||
{
|
||||
if (ring->mark == ring->consume) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear any mark set on the ring.
|
||||
*/
|
||||
|
||||
void
|
||||
ring_clear_mark(ring)
|
||||
Ring *ring;
|
||||
{
|
||||
ring->mark = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add characters from current segment to ring buffer.
|
||||
*/
|
||||
void
|
||||
ring_supplied(ring, count)
|
||||
Ring *ring;
|
||||
int count;
|
||||
{
|
||||
ring->supply = ring_increment(ring, ring->supply, count);
|
||||
ring->supplytime = ++ring_clock;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have just consumed "c" bytes.
|
||||
*/
|
||||
void
|
||||
ring_consumed(ring, count)
|
||||
Ring *ring;
|
||||
int count;
|
||||
{
|
||||
if (count == 0) /* don't update anything */
|
||||
return;
|
||||
|
||||
if (ring->mark &&
|
||||
(ring_subtract(ring, ring->mark, ring->consume) < count)) {
|
||||
ring->mark = 0;
|
||||
}
|
||||
#ifdef ENCRYPTION
|
||||
if (ring->consume < ring->clearto &&
|
||||
ring->clearto <= ring->consume + count)
|
||||
ring->clearto = 0;
|
||||
else if (ring->consume + count > ring->top &&
|
||||
ring->bottom <= ring->clearto &&
|
||||
ring->bottom + ((ring->consume + count) - ring->top))
|
||||
ring->clearto = 0;
|
||||
#endif /* ENCRYPTION */
|
||||
ring->consume = ring_increment(ring, ring->consume, count);
|
||||
ring->consumetime = ++ring_clock;
|
||||
/*
|
||||
* Try to encourage "ring_empty_consecutive()" to be large.
|
||||
*/
|
||||
if (ring_empty(ring)) {
|
||||
ring->consume = ring->supply = ring->bottom;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Buffer state query routines */
|
||||
|
||||
|
||||
/* Number of bytes that may be supplied */
|
||||
int
|
||||
ring_empty_count(ring)
|
||||
Ring *ring;
|
||||
{
|
||||
if (ring_empty(ring)) { /* if empty */
|
||||
return ring->size;
|
||||
} else {
|
||||
return ring_subtract(ring, ring->consume, ring->supply);
|
||||
}
|
||||
}
|
||||
|
||||
/* number of CONSECUTIVE bytes that may be supplied */
|
||||
int
|
||||
ring_empty_consecutive(ring)
|
||||
Ring *ring;
|
||||
{
|
||||
if ((ring->consume < ring->supply) || ring_empty(ring)) {
|
||||
/*
|
||||
* if consume is "below" supply, or empty, then
|
||||
* return distance to the top
|
||||
*/
|
||||
return ring_subtract(ring, ring->top, ring->supply);
|
||||
} else {
|
||||
/*
|
||||
* else, return what we may.
|
||||
*/
|
||||
return ring_subtract(ring, ring->consume, ring->supply);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the number of bytes that are available for consuming
|
||||
* (but don't give more than enough to get to cross over set mark)
|
||||
*/
|
||||
|
||||
int
|
||||
ring_full_count(ring)
|
||||
Ring *ring;
|
||||
{
|
||||
if ((ring->mark == 0) || (ring->mark == ring->consume)) {
|
||||
if (ring_full(ring)) {
|
||||
return ring->size; /* nothing consumed, but full */
|
||||
} else {
|
||||
return ring_subtract(ring, ring->supply, ring->consume);
|
||||
}
|
||||
} else {
|
||||
return ring_subtract(ring, ring->mark, ring->consume);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of CONSECUTIVE bytes available for consuming.
|
||||
* However, don't return more than enough to cross over set mark.
|
||||
*/
|
||||
int
|
||||
ring_full_consecutive(ring)
|
||||
Ring *ring;
|
||||
{
|
||||
if ((ring->mark == 0) || (ring->mark == ring->consume)) {
|
||||
if ((ring->supply < ring->consume) || ring_full(ring)) {
|
||||
return ring_subtract(ring, ring->top, ring->consume);
|
||||
} else {
|
||||
return ring_subtract(ring, ring->supply, ring->consume);
|
||||
}
|
||||
} else {
|
||||
if (ring->mark < ring->consume) {
|
||||
return ring_subtract(ring, ring->top, ring->consume);
|
||||
} else { /* Else, distance to mark */
|
||||
return ring_subtract(ring, ring->mark, ring->consume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Move data into the "supply" portion of of the ring buffer.
|
||||
*/
|
||||
void
|
||||
ring_supply_data(ring, buffer, count)
|
||||
Ring *ring;
|
||||
unsigned char *buffer;
|
||||
int count;
|
||||
{
|
||||
int i;
|
||||
|
||||
while (count) {
|
||||
i = MIN(count, ring_empty_consecutive(ring));
|
||||
memmove(ring->supply, buffer, i);
|
||||
ring_supplied(ring, i);
|
||||
count -= i;
|
||||
buffer += i;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
|
||||
/*
|
||||
* Move data from the "consume" portion of the ring buffer
|
||||
*/
|
||||
void
|
||||
ring_consume_data(ring, buffer, count)
|
||||
Ring *ring;
|
||||
unsigned char *buffer;
|
||||
int count;
|
||||
{
|
||||
int i;
|
||||
|
||||
while (count) {
|
||||
i = MIN(count, ring_full_consecutive(ring));
|
||||
memmove(buffer, ring->consume, i);
|
||||
ring_consumed(ring, i);
|
||||
count -= i;
|
||||
buffer += i;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
void
|
||||
ring_encrypt(ring, encryptor)
|
||||
Ring *ring;
|
||||
void (*encryptor)();
|
||||
{
|
||||
unsigned char *s, *c;
|
||||
|
||||
if (ring_empty(ring) || ring->clearto == ring->supply)
|
||||
return;
|
||||
|
||||
if (!(c = ring->clearto))
|
||||
c = ring->consume;
|
||||
|
||||
s = ring->supply;
|
||||
|
||||
if (s <= c) {
|
||||
(*encryptor)(c, ring->top - c);
|
||||
(*encryptor)(ring->bottom, s - ring->bottom);
|
||||
} else
|
||||
(*encryptor)(c, s - c);
|
||||
|
||||
ring->clearto = ring->supply;
|
||||
}
|
||||
|
||||
void
|
||||
ring_clearto(ring)
|
||||
Ring *ring;
|
||||
{
|
||||
if (!ring_empty(ring))
|
||||
ring->clearto = ring->supply;
|
||||
else
|
||||
ring->clearto = 0;
|
||||
}
|
||||
#endif /* ENCRYPTION */
|
105
contrib/telnet/telnet/ring.h
Normal file
105
contrib/telnet/telnet/ring.h
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)ring.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
#if defined(P)
|
||||
# undef P
|
||||
#endif
|
||||
|
||||
#if defined(__STDC__) || defined(LINT_ARGS)
|
||||
# define P(x) x
|
||||
#else
|
||||
# define P(x) ()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This defines a structure for a ring buffer.
|
||||
*
|
||||
* The circular buffer has two parts:
|
||||
*(((
|
||||
* full: [consume, supply)
|
||||
* empty: [supply, consume)
|
||||
*]]]
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char *consume, /* where data comes out of */
|
||||
*supply, /* where data comes in to */
|
||||
*bottom, /* lowest address in buffer */
|
||||
*top, /* highest address+1 in buffer */
|
||||
*mark; /* marker (user defined) */
|
||||
#ifdef ENCRYPTION
|
||||
unsigned char *clearto; /* Data to this point is clear text */
|
||||
unsigned char *encryyptedto; /* Data is encrypted to here */
|
||||
#endif /* ENCRYPTION */
|
||||
int size; /* size in bytes of buffer */
|
||||
u_long consumetime, /* help us keep straight full, empty, etc. */
|
||||
supplytime;
|
||||
} Ring;
|
||||
|
||||
/* Here are some functions and macros to deal with the ring buffer */
|
||||
|
||||
/* Initialization routine */
|
||||
extern int
|
||||
ring_init P((Ring *ring, unsigned char *buffer, int count));
|
||||
|
||||
/* Data movement routines */
|
||||
extern void
|
||||
ring_supply_data P((Ring *ring, unsigned char *buffer, int count));
|
||||
#ifdef notdef
|
||||
extern void
|
||||
ring_consume_data P((Ring *ring, unsigned char *buffer, int count));
|
||||
#endif
|
||||
|
||||
/* Buffer state transition routines */
|
||||
extern void
|
||||
ring_supplied P((Ring *ring, int count)),
|
||||
ring_consumed P((Ring *ring, int count));
|
||||
|
||||
/* Buffer state query routines */
|
||||
extern int
|
||||
ring_empty_count P((Ring *ring)),
|
||||
ring_empty_consecutive P((Ring *ring)),
|
||||
ring_full_count P((Ring *ring)),
|
||||
ring_full_consecutive P((Ring *ring));
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
extern void
|
||||
ring_encrypt P((Ring *ring, void (*func)())),
|
||||
ring_clearto P((Ring *ring));
|
||||
#endif /* ENCRYPTION */
|
||||
|
||||
extern void
|
||||
ring_clear_mark(),
|
||||
ring_mark();
|
1220
contrib/telnet/telnet/sys_bsd.c
Normal file
1220
contrib/telnet/telnet/sys_bsd.c
Normal file
File diff suppressed because it is too large
Load Diff
1366
contrib/telnet/telnet/telnet.1
Normal file
1366
contrib/telnet/telnet/telnet.1
Normal file
File diff suppressed because it is too large
Load Diff
2650
contrib/telnet/telnet/telnet.c
Normal file
2650
contrib/telnet/telnet/telnet.c
Normal file
File diff suppressed because it is too large
Load Diff
240
contrib/telnet/telnet/terminal.c
Normal file
240
contrib/telnet/telnet/terminal.c
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1990, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)terminal.c 8.2 (Berkeley) 2/16/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <arpa/telnet.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "ring.h"
|
||||
|
||||
#include "externs.h"
|
||||
#include "types.h"
|
||||
|
||||
Ring ttyoring, ttyiring;
|
||||
unsigned char ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ];
|
||||
|
||||
int termdata; /* Debugging flag */
|
||||
|
||||
#ifdef USE_TERMIO
|
||||
# ifndef VDISCARD
|
||||
cc_t termFlushChar;
|
||||
# endif
|
||||
# ifndef VLNEXT
|
||||
cc_t termLiteralNextChar;
|
||||
# endif
|
||||
# ifndef VSUSP
|
||||
cc_t termSuspChar;
|
||||
# endif
|
||||
# ifndef VWERASE
|
||||
cc_t termWerasChar;
|
||||
# endif
|
||||
# ifndef VREPRINT
|
||||
cc_t termRprntChar;
|
||||
# endif
|
||||
# ifndef VSTART
|
||||
cc_t termStartChar;
|
||||
# endif
|
||||
# ifndef VSTOP
|
||||
cc_t termStopChar;
|
||||
# endif
|
||||
# ifndef VEOL
|
||||
cc_t termForw1Char;
|
||||
# endif
|
||||
# ifndef VEOL2
|
||||
cc_t termForw2Char;
|
||||
# endif
|
||||
# ifndef VSTATUS
|
||||
cc_t termAytChar;
|
||||
# endif
|
||||
#else
|
||||
cc_t termForw2Char;
|
||||
cc_t termAytChar;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* initialize the terminal data structures.
|
||||
*/
|
||||
|
||||
void
|
||||
init_terminal()
|
||||
{
|
||||
if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
|
||||
exit(1);
|
||||
}
|
||||
if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
|
||||
exit(1);
|
||||
}
|
||||
autoflush = TerminalAutoFlush();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Send as much data as possible to the terminal.
|
||||
*
|
||||
* Return value:
|
||||
* -1: No useful work done, data waiting to go out.
|
||||
* 0: No data was waiting, so nothing was done.
|
||||
* 1: All waiting data was written out.
|
||||
* n: All data - n was written out.
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
ttyflush(drop)
|
||||
int drop;
|
||||
{
|
||||
register int n, n0, n1;
|
||||
|
||||
n0 = ring_full_count(&ttyoring);
|
||||
if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
|
||||
if (drop) {
|
||||
TerminalFlushOutput();
|
||||
/* we leave 'n' alone! */
|
||||
} else {
|
||||
n = TerminalWrite(ttyoring.consume, n);
|
||||
}
|
||||
}
|
||||
if (n > 0) {
|
||||
if (termdata && n) {
|
||||
Dump('>', ttyoring.consume, n);
|
||||
}
|
||||
/*
|
||||
* If we wrote everything, and the full count is
|
||||
* larger than what we wrote, then write the
|
||||
* rest of the buffer.
|
||||
*/
|
||||
if (n1 == n && n0 > n) {
|
||||
n1 = n0 - n;
|
||||
if (!drop)
|
||||
n1 = TerminalWrite(ttyoring.bottom, n1);
|
||||
if (n1 > 0)
|
||||
n += n1;
|
||||
}
|
||||
ring_consumed(&ttyoring, n);
|
||||
}
|
||||
if (n < 0)
|
||||
return -1;
|
||||
if (n == n0) {
|
||||
if (n0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
return n0 - n + 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These routines decides on what the mode should be (based on the values
|
||||
* of various global variables).
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
getconnmode()
|
||||
{
|
||||
extern int linemode;
|
||||
int mode = 0;
|
||||
#ifdef KLUDGELINEMODE
|
||||
extern int kludgelinemode;
|
||||
#endif
|
||||
|
||||
if (In3270)
|
||||
return(MODE_FLOW);
|
||||
|
||||
if (my_want_state_is_dont(TELOPT_ECHO))
|
||||
mode |= MODE_ECHO;
|
||||
|
||||
if (localflow)
|
||||
mode |= MODE_FLOW;
|
||||
|
||||
if (my_want_state_is_will(TELOPT_BINARY))
|
||||
mode |= MODE_INBIN;
|
||||
|
||||
if (his_want_state_is_will(TELOPT_BINARY))
|
||||
mode |= MODE_OUTBIN;
|
||||
|
||||
#ifdef KLUDGELINEMODE
|
||||
if (kludgelinemode) {
|
||||
if (my_want_state_is_dont(TELOPT_SGA)) {
|
||||
mode |= (MODE_TRAPSIG|MODE_EDIT);
|
||||
if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
|
||||
mode &= ~MODE_ECHO;
|
||||
}
|
||||
}
|
||||
return(mode);
|
||||
}
|
||||
#endif
|
||||
if (my_want_state_is_will(TELOPT_LINEMODE))
|
||||
mode |= linemode;
|
||||
return(mode);
|
||||
}
|
||||
|
||||
void
|
||||
setconnmode(force)
|
||||
int force;
|
||||
{
|
||||
#ifdef ENCRYPTION
|
||||
static int enc_passwd = 0;
|
||||
#endif /* ENCRYPTION */
|
||||
register int newmode;
|
||||
|
||||
newmode = getconnmode()|(force?MODE_FORCE:0);
|
||||
|
||||
TerminalNewMode(newmode);
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) {
|
||||
if (my_want_state_is_will(TELOPT_ENCRYPT)
|
||||
&& (enc_passwd == 0) && !encrypt_output) {
|
||||
encrypt_request_start(0, 0);
|
||||
enc_passwd = 1;
|
||||
}
|
||||
} else {
|
||||
if (enc_passwd) {
|
||||
encrypt_request_end();
|
||||
enc_passwd = 0;
|
||||
}
|
||||
}
|
||||
#endif /* ENCRYPTION */
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
setcommandmode()
|
||||
{
|
||||
TerminalNewMode(-1);
|
||||
}
|
411
contrib/telnet/telnet/tn3270.c
Normal file
411
contrib/telnet/telnet/tn3270.c
Normal file
@ -0,0 +1,411 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)tn3270.c 8.2 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <arpa/telnet.h>
|
||||
|
||||
#include "general.h"
|
||||
|
||||
#include "defines.h"
|
||||
#include "ring.h"
|
||||
#include "externs.h"
|
||||
#include "fdset.h"
|
||||
|
||||
#if defined(TN3270)
|
||||
|
||||
#include "../ctlr/screen.h"
|
||||
#include "../general/globals.h"
|
||||
|
||||
#include "../sys_curses/telextrn.h"
|
||||
#include "../ctlr/externs.h"
|
||||
|
||||
#if defined(unix)
|
||||
int
|
||||
HaveInput, /* There is input available to scan */
|
||||
cursesdata, /* Do we dump curses data? */
|
||||
sigiocount; /* Number of times we got a SIGIO */
|
||||
|
||||
char tline[200];
|
||||
char *transcom = 0; /* transparent mode command (default: none) */
|
||||
#endif /* defined(unix) */
|
||||
|
||||
char Ibuf[8*BUFSIZ], *Ifrontp, *Ibackp;
|
||||
|
||||
static char sb_terminal[] = { IAC, SB,
|
||||
TELOPT_TTYPE, TELQUAL_IS,
|
||||
'I', 'B', 'M', '-', '3', '2', '7', '8', '-', '2',
|
||||
IAC, SE };
|
||||
#define SBTERMMODEL 13
|
||||
|
||||
static int
|
||||
Sent3270TerminalType; /* Have we said we are a 3270? */
|
||||
|
||||
#endif /* defined(TN3270) */
|
||||
|
||||
|
||||
void
|
||||
init_3270()
|
||||
{
|
||||
#if defined(TN3270)
|
||||
#if defined(unix)
|
||||
HaveInput = 0;
|
||||
sigiocount = 0;
|
||||
#endif /* defined(unix) */
|
||||
Sent3270TerminalType = 0;
|
||||
Ifrontp = Ibackp = Ibuf;
|
||||
init_ctlr(); /* Initialize some things */
|
||||
init_keyboard();
|
||||
init_screen();
|
||||
init_system();
|
||||
#endif /* defined(TN3270) */
|
||||
}
|
||||
|
||||
|
||||
#if defined(TN3270)
|
||||
|
||||
/*
|
||||
* DataToNetwork - queue up some data to go to network. If "done" is set,
|
||||
* then when last byte is queued, we add on an IAC EOR sequence (so,
|
||||
* don't call us with "done" until you want that done...)
|
||||
*
|
||||
* We actually do send all the data to the network buffer, since our
|
||||
* only client needs for us to do that.
|
||||
*/
|
||||
|
||||
int
|
||||
DataToNetwork(buffer, count, done)
|
||||
register char *buffer; /* where the data is */
|
||||
register int count; /* how much to send */
|
||||
int done; /* is this the last of a logical block */
|
||||
{
|
||||
register int loop, c;
|
||||
int origCount;
|
||||
|
||||
origCount = count;
|
||||
|
||||
while (count) {
|
||||
/* If not enough room for EORs, IACs, etc., wait */
|
||||
if (NETROOM() < 6) {
|
||||
fd_set o;
|
||||
|
||||
FD_ZERO(&o);
|
||||
netflush();
|
||||
while (NETROOM() < 6) {
|
||||
FD_SET(net, &o);
|
||||
(void) select(net+1, (fd_set *) 0, &o, (fd_set *) 0,
|
||||
(struct timeval *) 0);
|
||||
netflush();
|
||||
}
|
||||
}
|
||||
c = ring_empty_count(&netoring);
|
||||
if (c > count) {
|
||||
c = count;
|
||||
}
|
||||
loop = c;
|
||||
while (loop) {
|
||||
if (((unsigned char)*buffer) == IAC) {
|
||||
break;
|
||||
}
|
||||
buffer++;
|
||||
loop--;
|
||||
}
|
||||
if ((c = c-loop)) {
|
||||
ring_supply_data(&netoring, buffer-c, c);
|
||||
count -= c;
|
||||
}
|
||||
if (loop) {
|
||||
NET2ADD(IAC, IAC);
|
||||
count--;
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
if (done) {
|
||||
NET2ADD(IAC, EOR);
|
||||
netflush(); /* try to move along as quickly as ... */
|
||||
}
|
||||
return(origCount - count);
|
||||
}
|
||||
|
||||
|
||||
#if defined(unix)
|
||||
void
|
||||
inputAvailable(signo)
|
||||
int signo;
|
||||
{
|
||||
HaveInput = 1;
|
||||
sigiocount++;
|
||||
}
|
||||
#endif /* defined(unix) */
|
||||
|
||||
void
|
||||
outputPurge()
|
||||
{
|
||||
(void) ttyflush(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The following routines are places where the various tn3270
|
||||
* routines make calls into telnet.c.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DataToTerminal - queue up some data to go to terminal.
|
||||
*
|
||||
* Note: there are people who call us and depend on our processing
|
||||
* *all* the data at one time (thus the select).
|
||||
*/
|
||||
|
||||
int
|
||||
DataToTerminal(buffer, count)
|
||||
register char *buffer; /* where the data is */
|
||||
register int count; /* how much to send */
|
||||
{
|
||||
register int c;
|
||||
int origCount;
|
||||
|
||||
origCount = count;
|
||||
|
||||
while (count) {
|
||||
if (TTYROOM() == 0) {
|
||||
#if defined(unix)
|
||||
fd_set o;
|
||||
|
||||
FD_ZERO(&o);
|
||||
#endif /* defined(unix) */
|
||||
(void) ttyflush(0);
|
||||
while (TTYROOM() == 0) {
|
||||
#if defined(unix)
|
||||
FD_SET(tout, &o);
|
||||
(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
|
||||
(struct timeval *) 0);
|
||||
#endif /* defined(unix) */
|
||||
(void) ttyflush(0);
|
||||
}
|
||||
}
|
||||
c = TTYROOM();
|
||||
if (c > count) {
|
||||
c = count;
|
||||
}
|
||||
ring_supply_data(&ttyoring, buffer, c);
|
||||
count -= c;
|
||||
buffer += c;
|
||||
}
|
||||
return(origCount);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Push3270 - Try to send data along the 3270 output (to screen) direction.
|
||||
*/
|
||||
|
||||
int
|
||||
Push3270()
|
||||
{
|
||||
int save = ring_full_count(&netiring);
|
||||
|
||||
if (save) {
|
||||
if (Ifrontp+save > Ibuf+sizeof Ibuf) {
|
||||
if (Ibackp != Ibuf) {
|
||||
memmove(Ibuf, Ibackp, Ifrontp-Ibackp);
|
||||
Ifrontp -= (Ibackp-Ibuf);
|
||||
Ibackp = Ibuf;
|
||||
}
|
||||
}
|
||||
if (Ifrontp+save < Ibuf+sizeof Ibuf) {
|
||||
(void)telrcv();
|
||||
}
|
||||
}
|
||||
return save != ring_full_count(&netiring);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish3270 - get the last dregs of 3270 data out to the terminal
|
||||
* before quitting.
|
||||
*/
|
||||
|
||||
void
|
||||
Finish3270()
|
||||
{
|
||||
while (Push3270() || !DoTerminalOutput()) {
|
||||
#if defined(unix)
|
||||
HaveInput = 0;
|
||||
#endif /* defined(unix) */
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* StringToTerminal - output a null terminated string to the terminal */
|
||||
|
||||
void
|
||||
StringToTerminal(s)
|
||||
char *s;
|
||||
{
|
||||
int count;
|
||||
|
||||
count = strlen(s);
|
||||
if (count) {
|
||||
(void) DataToTerminal(s, count); /* we know it always goes... */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if ((!defined(NOT43)) || defined(PUTCHAR))
|
||||
/* _putchar - output a single character to the terminal. This name is so that
|
||||
* curses(3x) can call us to send out data.
|
||||
*/
|
||||
|
||||
void
|
||||
_putchar(c)
|
||||
char c;
|
||||
{
|
||||
#if defined(sun) /* SunOS 4.0 bug */
|
||||
c &= 0x7f;
|
||||
#endif /* defined(sun) */
|
||||
if (cursesdata) {
|
||||
Dump('>', &c, 1);
|
||||
}
|
||||
if (!TTYROOM()) {
|
||||
(void) DataToTerminal(&c, 1);
|
||||
} else {
|
||||
TTYADD(c);
|
||||
}
|
||||
}
|
||||
#endif /* ((!defined(NOT43)) || defined(PUTCHAR)) */
|
||||
|
||||
void
|
||||
SetIn3270()
|
||||
{
|
||||
if (Sent3270TerminalType && my_want_state_is_will(TELOPT_BINARY)
|
||||
&& my_want_state_is_do(TELOPT_BINARY) && !donebinarytoggle) {
|
||||
if (!In3270) {
|
||||
In3270 = 1;
|
||||
Init3270(); /* Initialize 3270 functions */
|
||||
/* initialize terminal key mapping */
|
||||
InitTerminal(); /* Start terminal going */
|
||||
setconnmode(0);
|
||||
}
|
||||
} else {
|
||||
if (In3270) {
|
||||
StopScreen(1);
|
||||
In3270 = 0;
|
||||
Stop3270(); /* Tell 3270 we aren't here anymore */
|
||||
setconnmode(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* tn3270_ttype()
|
||||
*
|
||||
* Send a response to a terminal type negotiation.
|
||||
*
|
||||
* Return '0' if no more responses to send; '1' if a response sent.
|
||||
*/
|
||||
|
||||
int
|
||||
tn3270_ttype()
|
||||
{
|
||||
/*
|
||||
* Try to send a 3270 type terminal name. Decide which one based
|
||||
* on the format of our screen, and (in the future) color
|
||||
* capaiblities.
|
||||
*/
|
||||
InitTerminal(); /* Sets MaxNumberColumns, MaxNumberLines */
|
||||
if ((MaxNumberLines >= 24) && (MaxNumberColumns >= 80)) {
|
||||
Sent3270TerminalType = 1;
|
||||
if ((MaxNumberLines >= 27) && (MaxNumberColumns >= 132)) {
|
||||
MaxNumberLines = 27;
|
||||
MaxNumberColumns = 132;
|
||||
sb_terminal[SBTERMMODEL] = '5';
|
||||
} else if (MaxNumberLines >= 43) {
|
||||
MaxNumberLines = 43;
|
||||
MaxNumberColumns = 80;
|
||||
sb_terminal[SBTERMMODEL] = '4';
|
||||
} else if (MaxNumberLines >= 32) {
|
||||
MaxNumberLines = 32;
|
||||
MaxNumberColumns = 80;
|
||||
sb_terminal[SBTERMMODEL] = '3';
|
||||
} else {
|
||||
MaxNumberLines = 24;
|
||||
MaxNumberColumns = 80;
|
||||
sb_terminal[SBTERMMODEL] = '2';
|
||||
}
|
||||
NumberLines = 24; /* before we start out... */
|
||||
NumberColumns = 80;
|
||||
ScreenSize = NumberLines*NumberColumns;
|
||||
if ((MaxNumberLines*MaxNumberColumns) > MAXSCREENSIZE) {
|
||||
ExitString("Programming error: MAXSCREENSIZE too small.\n",
|
||||
1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
printsub('>', sb_terminal+2, sizeof sb_terminal-2);
|
||||
ring_supply_data(&netoring, sb_terminal, sizeof sb_terminal);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(unix)
|
||||
int
|
||||
settranscom(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc == 1 && transcom) {
|
||||
transcom = 0;
|
||||
}
|
||||
if (argc == 1) {
|
||||
return 1;
|
||||
}
|
||||
transcom = tline;
|
||||
(void) strcpy(transcom, argv[1]);
|
||||
for (i = 2; i < argc; ++i) {
|
||||
(void) strcat(transcom, " ");
|
||||
(void) strcat(transcom, argv[i]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif /* defined(unix) */
|
||||
|
||||
#endif /* defined(TN3270) */
|
52
contrib/telnet/telnet/types.h
Normal file
52
contrib/telnet/telnet/types.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)types.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *modedescriptions;
|
||||
char modetype;
|
||||
} Modelist;
|
||||
|
||||
extern Modelist modelist[];
|
||||
|
||||
typedef struct {
|
||||
int
|
||||
system, /* what the current time is */
|
||||
echotoggle, /* last time user entered echo character */
|
||||
modenegotiated, /* last time operating mode negotiated */
|
||||
didnetreceive, /* last time we read data from network */
|
||||
gotDM; /* when did we last see a data mark */
|
||||
} Clocks;
|
||||
|
||||
extern Clocks clocks;
|
939
contrib/telnet/telnet/utilities.c
Normal file
939
contrib/telnet/telnet/utilities.c
Normal file
@ -0,0 +1,939 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)utilities.c 8.3 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#define TELOPTS
|
||||
#define TELCMDS
|
||||
#define SLC_NAMES
|
||||
#include <arpa/telnet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "general.h"
|
||||
|
||||
#include "fdset.h"
|
||||
|
||||
#include "ring.h"
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#include "externs.h"
|
||||
|
||||
FILE *NetTrace = 0; /* Not in bss, since needs to stay */
|
||||
int prettydump;
|
||||
|
||||
/*
|
||||
* upcase()
|
||||
*
|
||||
* Upcase (in place) the argument.
|
||||
*/
|
||||
|
||||
void
|
||||
upcase(argument)
|
||||
register char *argument;
|
||||
{
|
||||
register int c;
|
||||
|
||||
while ((c = *argument) != 0) {
|
||||
if (islower(c)) {
|
||||
*argument = toupper(c);
|
||||
}
|
||||
argument++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SetSockOpt()
|
||||
*
|
||||
* Compensate for differences in 4.2 and 4.3 systems.
|
||||
*/
|
||||
|
||||
int
|
||||
SetSockOpt(fd, level, option, yesno)
|
||||
int fd, level, option, yesno;
|
||||
{
|
||||
#ifndef NOT43
|
||||
return setsockopt(fd, level, option,
|
||||
(char *)&yesno, sizeof yesno);
|
||||
#else /* NOT43 */
|
||||
if (yesno == 0) { /* Can't do that in 4.2! */
|
||||
fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n",
|
||||
option);
|
||||
return -1;
|
||||
}
|
||||
return setsockopt(fd, level, option, 0, 0);
|
||||
#endif /* NOT43 */
|
||||
}
|
||||
|
||||
/*
|
||||
* The following are routines used to print out debugging information.
|
||||
*/
|
||||
|
||||
unsigned char NetTraceFile[256] = "(standard output)";
|
||||
|
||||
void
|
||||
SetNetTrace(file)
|
||||
register char *file;
|
||||
{
|
||||
if (NetTrace && NetTrace != stdout)
|
||||
fclose(NetTrace);
|
||||
if (file && (strcmp(file, "-") != 0)) {
|
||||
NetTrace = fopen(file, "w");
|
||||
if (NetTrace) {
|
||||
strcpy((char *)NetTraceFile, file);
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "Cannot open %s.\n", file);
|
||||
}
|
||||
NetTrace = stdout;
|
||||
strcpy((char *)NetTraceFile, "(standard output)");
|
||||
}
|
||||
|
||||
void
|
||||
Dump(direction, buffer, length)
|
||||
char direction;
|
||||
unsigned char *buffer;
|
||||
int length;
|
||||
{
|
||||
# define BYTES_PER_LINE 32
|
||||
# define min(x,y) ((x<y)? x:y)
|
||||
unsigned char *pThis;
|
||||
int offset;
|
||||
extern pettydump;
|
||||
|
||||
offset = 0;
|
||||
|
||||
while (length) {
|
||||
/* print one line */
|
||||
fprintf(NetTrace, "%c 0x%x\t", direction, offset);
|
||||
pThis = buffer;
|
||||
if (prettydump) {
|
||||
buffer = buffer + min(length, BYTES_PER_LINE/2);
|
||||
while (pThis < buffer) {
|
||||
fprintf(NetTrace, "%c%.2x",
|
||||
(((*pThis)&0xff) == 0xff) ? '*' : ' ',
|
||||
(*pThis)&0xff);
|
||||
pThis++;
|
||||
}
|
||||
length -= BYTES_PER_LINE/2;
|
||||
offset += BYTES_PER_LINE/2;
|
||||
} else {
|
||||
buffer = buffer + min(length, BYTES_PER_LINE);
|
||||
while (pThis < buffer) {
|
||||
fprintf(NetTrace, "%.2x", (*pThis)&0xff);
|
||||
pThis++;
|
||||
}
|
||||
length -= BYTES_PER_LINE;
|
||||
offset += BYTES_PER_LINE;
|
||||
}
|
||||
if (NetTrace == stdout) {
|
||||
fprintf(NetTrace, "\r\n");
|
||||
} else {
|
||||
fprintf(NetTrace, "\n");
|
||||
}
|
||||
if (length < 0) {
|
||||
fflush(NetTrace);
|
||||
return;
|
||||
}
|
||||
/* find next unique line */
|
||||
}
|
||||
fflush(NetTrace);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
printoption(direction, cmd, option)
|
||||
char *direction;
|
||||
int cmd, option;
|
||||
{
|
||||
if (!showoptions)
|
||||
return;
|
||||
if (cmd == IAC) {
|
||||
if (TELCMD_OK(option))
|
||||
fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option));
|
||||
else
|
||||
fprintf(NetTrace, "%s IAC %d", direction, option);
|
||||
} else {
|
||||
register char *fmt;
|
||||
fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
|
||||
(cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
|
||||
if (fmt) {
|
||||
fprintf(NetTrace, "%s %s ", direction, fmt);
|
||||
if (TELOPT_OK(option))
|
||||
fprintf(NetTrace, "%s", TELOPT(option));
|
||||
else if (option == TELOPT_EXOPL)
|
||||
fprintf(NetTrace, "EXOPL");
|
||||
else
|
||||
fprintf(NetTrace, "%d", option);
|
||||
} else
|
||||
fprintf(NetTrace, "%s %d %d", direction, cmd, option);
|
||||
}
|
||||
if (NetTrace == stdout) {
|
||||
fprintf(NetTrace, "\r\n");
|
||||
fflush(NetTrace);
|
||||
} else {
|
||||
fprintf(NetTrace, "\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
optionstatus()
|
||||
{
|
||||
register int i;
|
||||
extern char will_wont_resp[], do_dont_resp[];
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (do_dont_resp[i]) {
|
||||
if (TELOPT_OK(i))
|
||||
printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
|
||||
else if (TELCMD_OK(i))
|
||||
printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
|
||||
else
|
||||
printf("resp DO_DONT %d: %d\n", i,
|
||||
do_dont_resp[i]);
|
||||
if (my_want_state_is_do(i)) {
|
||||
if (TELOPT_OK(i))
|
||||
printf("want DO %s\n", TELOPT(i));
|
||||
else if (TELCMD_OK(i))
|
||||
printf("want DO %s\n", TELCMD(i));
|
||||
else
|
||||
printf("want DO %d\n", i);
|
||||
} else {
|
||||
if (TELOPT_OK(i))
|
||||
printf("want DONT %s\n", TELOPT(i));
|
||||
else if (TELCMD_OK(i))
|
||||
printf("want DONT %s\n", TELCMD(i));
|
||||
else
|
||||
printf("want DONT %d\n", i);
|
||||
}
|
||||
} else {
|
||||
if (my_state_is_do(i)) {
|
||||
if (TELOPT_OK(i))
|
||||
printf(" DO %s\n", TELOPT(i));
|
||||
else if (TELCMD_OK(i))
|
||||
printf(" DO %s\n", TELCMD(i));
|
||||
else
|
||||
printf(" DO %d\n", i);
|
||||
}
|
||||
}
|
||||
if (will_wont_resp[i]) {
|
||||
if (TELOPT_OK(i))
|
||||
printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
|
||||
else if (TELCMD_OK(i))
|
||||
printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
|
||||
else
|
||||
printf("resp WILL_WONT %d: %d\n",
|
||||
i, will_wont_resp[i]);
|
||||
if (my_want_state_is_will(i)) {
|
||||
if (TELOPT_OK(i))
|
||||
printf("want WILL %s\n", TELOPT(i));
|
||||
else if (TELCMD_OK(i))
|
||||
printf("want WILL %s\n", TELCMD(i));
|
||||
else
|
||||
printf("want WILL %d\n", i);
|
||||
} else {
|
||||
if (TELOPT_OK(i))
|
||||
printf("want WONT %s\n", TELOPT(i));
|
||||
else if (TELCMD_OK(i))
|
||||
printf("want WONT %s\n", TELCMD(i));
|
||||
else
|
||||
printf("want WONT %d\n", i);
|
||||
}
|
||||
} else {
|
||||
if (my_state_is_will(i)) {
|
||||
if (TELOPT_OK(i))
|
||||
printf(" WILL %s\n", TELOPT(i));
|
||||
else if (TELCMD_OK(i))
|
||||
printf(" WILL %s\n", TELCMD(i));
|
||||
else
|
||||
printf(" WILL %d\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
printsub(direction, pointer, length)
|
||||
char direction; /* '<' or '>' */
|
||||
unsigned char *pointer; /* where suboption data sits */
|
||||
int length; /* length of suboption data */
|
||||
{
|
||||
register int i;
|
||||
char buf[512];
|
||||
extern int want_status_response;
|
||||
|
||||
if (showoptions || direction == 0 ||
|
||||
(want_status_response && (pointer[0] == TELOPT_STATUS))) {
|
||||
if (direction) {
|
||||
fprintf(NetTrace, "%s IAC SB ",
|
||||
(direction == '<')? "RCVD":"SENT");
|
||||
if (length >= 3) {
|
||||
register int j;
|
||||
|
||||
i = pointer[length-2];
|
||||
j = pointer[length-1];
|
||||
|
||||
if (i != IAC || j != SE) {
|
||||
fprintf(NetTrace, "(terminated by ");
|
||||
if (TELOPT_OK(i))
|
||||
fprintf(NetTrace, "%s ", TELOPT(i));
|
||||
else if (TELCMD_OK(i))
|
||||
fprintf(NetTrace, "%s ", TELCMD(i));
|
||||
else
|
||||
fprintf(NetTrace, "%d ", i);
|
||||
if (TELOPT_OK(j))
|
||||
fprintf(NetTrace, "%s", TELOPT(j));
|
||||
else if (TELCMD_OK(j))
|
||||
fprintf(NetTrace, "%s", TELCMD(j));
|
||||
else
|
||||
fprintf(NetTrace, "%d", j);
|
||||
fprintf(NetTrace, ", not IAC SE!) ");
|
||||
}
|
||||
}
|
||||
length -= 2;
|
||||
}
|
||||
if (length < 1) {
|
||||
fprintf(NetTrace, "(Empty suboption??\?)");
|
||||
if (NetTrace == stdout)
|
||||
fflush(NetTrace);
|
||||
return;
|
||||
}
|
||||
switch (pointer[0]) {
|
||||
case TELOPT_TTYPE:
|
||||
fprintf(NetTrace, "TERMINAL-TYPE ");
|
||||
switch (pointer[1]) {
|
||||
case TELQUAL_IS:
|
||||
fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
|
||||
break;
|
||||
case TELQUAL_SEND:
|
||||
fprintf(NetTrace, "SEND");
|
||||
break;
|
||||
default:
|
||||
fprintf(NetTrace,
|
||||
"- unknown qualifier %d (0x%x).",
|
||||
pointer[1], pointer[1]);
|
||||
}
|
||||
break;
|
||||
case TELOPT_TSPEED:
|
||||
fprintf(NetTrace, "TERMINAL-SPEED");
|
||||
if (length < 2) {
|
||||
fprintf(NetTrace, " (empty suboption??\?)");
|
||||
break;
|
||||
}
|
||||
switch (pointer[1]) {
|
||||
case TELQUAL_IS:
|
||||
fprintf(NetTrace, " IS ");
|
||||
fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2);
|
||||
break;
|
||||
default:
|
||||
if (pointer[1] == 1)
|
||||
fprintf(NetTrace, " SEND");
|
||||
else
|
||||
fprintf(NetTrace, " %d (unknown)", pointer[1]);
|
||||
for (i = 2; i < length; i++)
|
||||
fprintf(NetTrace, " ?%d?", pointer[i]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case TELOPT_LFLOW:
|
||||
fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
|
||||
if (length < 2) {
|
||||
fprintf(NetTrace, " (empty suboption??\?)");
|
||||
break;
|
||||
}
|
||||
switch (pointer[1]) {
|
||||
case LFLOW_OFF:
|
||||
fprintf(NetTrace, " OFF"); break;
|
||||
case LFLOW_ON:
|
||||
fprintf(NetTrace, " ON"); break;
|
||||
case LFLOW_RESTART_ANY:
|
||||
fprintf(NetTrace, " RESTART-ANY"); break;
|
||||
case LFLOW_RESTART_XON:
|
||||
fprintf(NetTrace, " RESTART-XON"); break;
|
||||
default:
|
||||
fprintf(NetTrace, " %d (unknown)", pointer[1]);
|
||||
}
|
||||
for (i = 2; i < length; i++)
|
||||
fprintf(NetTrace, " ?%d?", pointer[i]);
|
||||
break;
|
||||
|
||||
case TELOPT_NAWS:
|
||||
fprintf(NetTrace, "NAWS");
|
||||
if (length < 2) {
|
||||
fprintf(NetTrace, " (empty suboption??\?)");
|
||||
break;
|
||||
}
|
||||
if (length == 2) {
|
||||
fprintf(NetTrace, " ?%d?", pointer[1]);
|
||||
break;
|
||||
}
|
||||
fprintf(NetTrace, " %d %d (%d)",
|
||||
pointer[1], pointer[2],
|
||||
(int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
|
||||
if (length == 4) {
|
||||
fprintf(NetTrace, " ?%d?", pointer[3]);
|
||||
break;
|
||||
}
|
||||
fprintf(NetTrace, " %d %d (%d)",
|
||||
pointer[3], pointer[4],
|
||||
(int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
|
||||
for (i = 5; i < length; i++)
|
||||
fprintf(NetTrace, " ?%d?", pointer[i]);
|
||||
break;
|
||||
|
||||
#if defined(AUTHENTICATION)
|
||||
case TELOPT_AUTHENTICATION:
|
||||
fprintf(NetTrace, "AUTHENTICATION");
|
||||
if (length < 2) {
|
||||
fprintf(NetTrace, " (empty suboption??\?)");
|
||||
break;
|
||||
}
|
||||
switch (pointer[1]) {
|
||||
case TELQUAL_REPLY:
|
||||
case TELQUAL_IS:
|
||||
fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ?
|
||||
"IS" : "REPLY");
|
||||
if (AUTHTYPE_NAME_OK(pointer[2]))
|
||||
fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2]));
|
||||
else
|
||||
fprintf(NetTrace, "%d ", pointer[2]);
|
||||
if (length < 3) {
|
||||
fprintf(NetTrace, "(partial suboption??\?)");
|
||||
break;
|
||||
}
|
||||
fprintf(NetTrace, "%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));
|
||||
fprintf(NetTrace, "%s", buf);
|
||||
break;
|
||||
|
||||
case TELQUAL_SEND:
|
||||
i = 2;
|
||||
fprintf(NetTrace, " SEND ");
|
||||
while (i < length) {
|
||||
if (AUTHTYPE_NAME_OK(pointer[i]))
|
||||
fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i]));
|
||||
else
|
||||
fprintf(NetTrace, "%d ", pointer[i]);
|
||||
if (++i >= length) {
|
||||
fprintf(NetTrace, "(partial suboption??\?)");
|
||||
break;
|
||||
}
|
||||
fprintf(NetTrace, "%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;
|
||||
fprintf(NetTrace, " NAME \"");
|
||||
while (i < length)
|
||||
putc(pointer[i++], NetTrace);
|
||||
putc('"', NetTrace);
|
||||
break;
|
||||
|
||||
default:
|
||||
for (i = 2; i < length; i++)
|
||||
fprintf(NetTrace, " ?%d?", pointer[i]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
case TELOPT_ENCRYPT:
|
||||
fprintf(NetTrace, "ENCRYPT");
|
||||
if (length < 2) {
|
||||
fprintf(NetTrace, " (empty suboption??\?)");
|
||||
break;
|
||||
}
|
||||
switch (pointer[1]) {
|
||||
case ENCRYPT_START:
|
||||
fprintf(NetTrace, " START");
|
||||
break;
|
||||
|
||||
case ENCRYPT_END:
|
||||
fprintf(NetTrace, " END");
|
||||
break;
|
||||
|
||||
case ENCRYPT_REQSTART:
|
||||
fprintf(NetTrace, " REQUEST-START");
|
||||
break;
|
||||
|
||||
case ENCRYPT_REQEND:
|
||||
fprintf(NetTrace, " REQUEST-END");
|
||||
break;
|
||||
|
||||
case ENCRYPT_IS:
|
||||
case ENCRYPT_REPLY:
|
||||
fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ?
|
||||
"IS" : "REPLY");
|
||||
if (length < 3) {
|
||||
fprintf(NetTrace, " (partial suboption??\?)");
|
||||
break;
|
||||
}
|
||||
if (ENCTYPE_NAME_OK(pointer[2]))
|
||||
fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[2]));
|
||||
else
|
||||
fprintf(NetTrace, " %d (unknown)", pointer[2]);
|
||||
|
||||
encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf));
|
||||
fprintf(NetTrace, "%s", buf);
|
||||
break;
|
||||
|
||||
case ENCRYPT_SUPPORT:
|
||||
i = 2;
|
||||
fprintf(NetTrace, " SUPPORT ");
|
||||
while (i < length) {
|
||||
if (ENCTYPE_NAME_OK(pointer[i]))
|
||||
fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[i]));
|
||||
else
|
||||
fprintf(NetTrace, "%d ", pointer[i]);
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCRYPT_ENC_KEYID:
|
||||
fprintf(NetTrace, " ENC_KEYID ");
|
||||
goto encommon;
|
||||
|
||||
case ENCRYPT_DEC_KEYID:
|
||||
fprintf(NetTrace, " DEC_KEYID ");
|
||||
goto encommon;
|
||||
|
||||
default:
|
||||
fprintf(NetTrace, " %d (unknown)", pointer[1]);
|
||||
encommon:
|
||||
for (i = 2; i < length; i++)
|
||||
fprintf(NetTrace, " %d", pointer[i]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif /* ENCRYPTION */
|
||||
|
||||
case TELOPT_LINEMODE:
|
||||
fprintf(NetTrace, "LINEMODE ");
|
||||
if (length < 2) {
|
||||
fprintf(NetTrace, " (empty suboption??\?)");
|
||||
break;
|
||||
}
|
||||
switch (pointer[1]) {
|
||||
case WILL:
|
||||
fprintf(NetTrace, "WILL ");
|
||||
goto common;
|
||||
case WONT:
|
||||
fprintf(NetTrace, "WONT ");
|
||||
goto common;
|
||||
case DO:
|
||||
fprintf(NetTrace, "DO ");
|
||||
goto common;
|
||||
case DONT:
|
||||
fprintf(NetTrace, "DONT ");
|
||||
common:
|
||||
if (length < 3) {
|
||||
fprintf(NetTrace, "(no option??\?)");
|
||||
break;
|
||||
}
|
||||
switch (pointer[2]) {
|
||||
case LM_FORWARDMASK:
|
||||
fprintf(NetTrace, "Forward Mask");
|
||||
for (i = 3; i < length; i++)
|
||||
fprintf(NetTrace, " %x", pointer[i]);
|
||||
break;
|
||||
default:
|
||||
fprintf(NetTrace, "%d (unknown)", pointer[2]);
|
||||
for (i = 3; i < length; i++)
|
||||
fprintf(NetTrace, " %d", pointer[i]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case LM_SLC:
|
||||
fprintf(NetTrace, "SLC");
|
||||
for (i = 2; i < length - 2; i += 3) {
|
||||
if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
|
||||
fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
|
||||
else
|
||||
fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
|
||||
switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
|
||||
case SLC_NOSUPPORT:
|
||||
fprintf(NetTrace, " NOSUPPORT"); break;
|
||||
case SLC_CANTCHANGE:
|
||||
fprintf(NetTrace, " CANTCHANGE"); break;
|
||||
case SLC_VARIABLE:
|
||||
fprintf(NetTrace, " VARIABLE"); break;
|
||||
case SLC_DEFAULT:
|
||||
fprintf(NetTrace, " DEFAULT"); break;
|
||||
}
|
||||
fprintf(NetTrace, "%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))
|
||||
fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
|
||||
fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
|
||||
if ((pointer[i+SLC_VALUE] == IAC) &&
|
||||
(pointer[i+SLC_VALUE+1] == IAC))
|
||||
i++;
|
||||
}
|
||||
for (; i < length; i++)
|
||||
fprintf(NetTrace, " ?%d?", pointer[i]);
|
||||
break;
|
||||
|
||||
case LM_MODE:
|
||||
fprintf(NetTrace, "MODE ");
|
||||
if (length < 3) {
|
||||
fprintf(NetTrace, "(no mode??\?)");
|
||||
break;
|
||||
}
|
||||
{
|
||||
char tbuf[64];
|
||||
sprintf(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" : "");
|
||||
fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
|
||||
}
|
||||
if (pointer[2]&~(MODE_MASK))
|
||||
fprintf(NetTrace, " (0x%x)", pointer[2]);
|
||||
for (i = 3; i < length; i++)
|
||||
fprintf(NetTrace, " ?0x%x?", pointer[i]);
|
||||
break;
|
||||
default:
|
||||
fprintf(NetTrace, "%d (unknown)", pointer[1]);
|
||||
for (i = 2; i < length; i++)
|
||||
fprintf(NetTrace, " %d", pointer[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case TELOPT_STATUS: {
|
||||
register char *cp;
|
||||
register int j, k;
|
||||
|
||||
fprintf(NetTrace, "STATUS");
|
||||
|
||||
switch (pointer[1]) {
|
||||
default:
|
||||
if (pointer[1] == TELQUAL_SEND)
|
||||
fprintf(NetTrace, " SEND");
|
||||
else
|
||||
fprintf(NetTrace, " %d (unknown)", pointer[1]);
|
||||
for (i = 2; i < length; i++)
|
||||
fprintf(NetTrace, " ?%d?", pointer[i]);
|
||||
break;
|
||||
case TELQUAL_IS:
|
||||
if (--want_status_response < 0)
|
||||
want_status_response = 0;
|
||||
if (NetTrace == stdout)
|
||||
fprintf(NetTrace, " IS\r\n");
|
||||
else
|
||||
fprintf(NetTrace, " IS\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((int)pointer[i]))
|
||||
fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
|
||||
else
|
||||
fprintf(NetTrace, " %s %d", cp, pointer[i]);
|
||||
|
||||
if (NetTrace == stdout)
|
||||
fprintf(NetTrace, "\r\n");
|
||||
else
|
||||
fprintf(NetTrace, "\n");
|
||||
break;
|
||||
|
||||
case SB:
|
||||
fprintf(NetTrace, " 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) {
|
||||
fprintf(NetTrace, " SE");
|
||||
i = j;
|
||||
} else
|
||||
i = j - 1;
|
||||
|
||||
if (NetTrace == stdout)
|
||||
fprintf(NetTrace, "\r\n");
|
||||
else
|
||||
fprintf(NetTrace, "\n");
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(NetTrace, " %d", pointer[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TELOPT_XDISPLOC:
|
||||
fprintf(NetTrace, "X-DISPLAY-LOCATION ");
|
||||
switch (pointer[1]) {
|
||||
case TELQUAL_IS:
|
||||
fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
|
||||
break;
|
||||
case TELQUAL_SEND:
|
||||
fprintf(NetTrace, "SEND");
|
||||
break;
|
||||
default:
|
||||
fprintf(NetTrace, "- unknown qualifier %d (0x%x).",
|
||||
pointer[1], pointer[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case TELOPT_NEW_ENVIRON:
|
||||
fprintf(NetTrace, "NEW-ENVIRON ");
|
||||
#ifdef OLD_ENVIRON
|
||||
goto env_common1;
|
||||
case TELOPT_OLD_ENVIRON:
|
||||
fprintf(NetTrace, "OLD-ENVIRON");
|
||||
env_common1:
|
||||
#endif
|
||||
switch (pointer[1]) {
|
||||
case TELQUAL_IS:
|
||||
fprintf(NetTrace, "IS ");
|
||||
goto env_common;
|
||||
case TELQUAL_SEND:
|
||||
fprintf(NetTrace, "SEND ");
|
||||
goto env_common;
|
||||
case TELQUAL_INFO:
|
||||
fprintf(NetTrace, "INFO ");
|
||||
env_common:
|
||||
{
|
||||
register int noquote = 2;
|
||||
#if defined(ENV_HACK) && defined(OLD_ENVIRON)
|
||||
extern int old_env_var, old_env_value;
|
||||
#endif
|
||||
for (i = 2; i < length; i++ ) {
|
||||
switch (pointer[i]) {
|
||||
case NEW_ENV_VALUE:
|
||||
#ifdef OLD_ENVIRON
|
||||
/* case NEW_ENV_OVAR: */
|
||||
if (pointer[0] == TELOPT_OLD_ENVIRON) {
|
||||
# ifdef ENV_HACK
|
||||
if (old_env_var == OLD_ENV_VALUE)
|
||||
fprintf(NetTrace, "\" (VALUE) " + noquote);
|
||||
else
|
||||
# endif
|
||||
fprintf(NetTrace, "\" VAR " + noquote);
|
||||
} else
|
||||
#endif /* OLD_ENVIRON */
|
||||
fprintf(NetTrace, "\" VALUE " + noquote);
|
||||
noquote = 2;
|
||||
break;
|
||||
|
||||
case NEW_ENV_VAR:
|
||||
#ifdef OLD_ENVIRON
|
||||
/* case OLD_ENV_VALUE: */
|
||||
if (pointer[0] == TELOPT_OLD_ENVIRON) {
|
||||
# ifdef ENV_HACK
|
||||
if (old_env_value == OLD_ENV_VAR)
|
||||
fprintf(NetTrace, "\" (VAR) " + noquote);
|
||||
else
|
||||
# endif
|
||||
fprintf(NetTrace, "\" VALUE " + noquote);
|
||||
} else
|
||||
#endif /* OLD_ENVIRON */
|
||||
fprintf(NetTrace, "\" VAR " + noquote);
|
||||
noquote = 2;
|
||||
break;
|
||||
|
||||
case ENV_ESC:
|
||||
fprintf(NetTrace, "\" ESC " + noquote);
|
||||
noquote = 2;
|
||||
break;
|
||||
|
||||
case ENV_USERVAR:
|
||||
fprintf(NetTrace, "\" USERVAR " + noquote);
|
||||
noquote = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
def_case:
|
||||
if (isprint(pointer[i]) && pointer[i] != '"') {
|
||||
if (noquote) {
|
||||
putc('"', NetTrace);
|
||||
noquote = 0;
|
||||
}
|
||||
putc(pointer[i], NetTrace);
|
||||
} else {
|
||||
fprintf(NetTrace, "\" %03o " + noquote,
|
||||
pointer[i]);
|
||||
noquote = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!noquote)
|
||||
putc('"', NetTrace);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (TELOPT_OK(pointer[0]))
|
||||
fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
|
||||
else
|
||||
fprintf(NetTrace, "%d (unknown)", pointer[0]);
|
||||
for (i = 1; i < length; i++)
|
||||
fprintf(NetTrace, " %d", pointer[i]);
|
||||
break;
|
||||
}
|
||||
if (direction) {
|
||||
if (NetTrace == stdout)
|
||||
fprintf(NetTrace, "\r\n");
|
||||
else
|
||||
fprintf(NetTrace, "\n");
|
||||
}
|
||||
if (NetTrace == stdout)
|
||||
fflush(NetTrace);
|
||||
}
|
||||
}
|
||||
|
||||
/* EmptyTerminal - called to make sure that the terminal buffer is empty.
|
||||
* Note that we consider the buffer to run all the
|
||||
* way to the kernel (thus the select).
|
||||
*/
|
||||
|
||||
void
|
||||
EmptyTerminal()
|
||||
{
|
||||
#if defined(unix)
|
||||
fd_set o;
|
||||
|
||||
FD_ZERO(&o);
|
||||
#endif /* defined(unix) */
|
||||
|
||||
if (TTYBYTES() == 0) {
|
||||
#if defined(unix)
|
||||
FD_SET(tout, &o);
|
||||
(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
|
||||
(struct timeval *) 0); /* wait for TTLOWAT */
|
||||
#endif /* defined(unix) */
|
||||
} else {
|
||||
while (TTYBYTES()) {
|
||||
(void) ttyflush(0);
|
||||
#if defined(unix)
|
||||
FD_SET(tout, &o);
|
||||
(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
|
||||
(struct timeval *) 0); /* wait for TTLOWAT */
|
||||
#endif /* defined(unix) */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SetForExit()
|
||||
{
|
||||
setconnmode(0);
|
||||
#if defined(TN3270)
|
||||
if (In3270) {
|
||||
Finish3270();
|
||||
}
|
||||
#else /* defined(TN3270) */
|
||||
do {
|
||||
(void)telrcv(); /* Process any incoming data */
|
||||
EmptyTerminal();
|
||||
} while (ring_full_count(&netiring)); /* While there is any */
|
||||
#endif /* defined(TN3270) */
|
||||
setcommandmode();
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
#if defined(TN3270)
|
||||
if (In3270) {
|
||||
StopScreen(1);
|
||||
}
|
||||
#endif /* defined(TN3270) */
|
||||
setconnmode(0);
|
||||
EmptyTerminal(); /* Flush the path to the tty */
|
||||
setcommandmode();
|
||||
}
|
||||
|
||||
void
|
||||
Exit(returnCode)
|
||||
int returnCode;
|
||||
{
|
||||
SetForExit();
|
||||
exit(returnCode);
|
||||
}
|
||||
|
||||
void
|
||||
ExitString(string, returnCode)
|
||||
char *string;
|
||||
int returnCode;
|
||||
{
|
||||
SetForExit();
|
||||
fwrite(string, 1, strlen(string), stderr);
|
||||
exit(returnCode);
|
||||
}
|
91
contrib/telnet/telnetd/authenc.c
Normal file
91
contrib/telnet/telnetd/authenc.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*-
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)authenc.c 8.2 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#if defined(AUTHENTICATION) || defined(ENCRYPTION)
|
||||
#include "telnetd.h"
|
||||
#include <libtelnet/misc.h>
|
||||
|
||||
int
|
||||
net_write(str, len)
|
||||
unsigned char *str;
|
||||
int len;
|
||||
{
|
||||
if (nfrontp + len < netobuf + BUFSIZ) {
|
||||
memmove((void *)nfrontp, (void *)str, len);
|
||||
nfrontp += len;
|
||||
return(len);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
net_encrypt()
|
||||
{
|
||||
#ifdef ENCRYPTION
|
||||
char *s = (nclearto > nbackp) ? nclearto : nbackp;
|
||||
if (s < nfrontp && encrypt_output) {
|
||||
(*encrypt_output)((unsigned char *)s, nfrontp - s);
|
||||
}
|
||||
nclearto = nfrontp;
|
||||
#endif /* ENCRYPTION */
|
||||
}
|
||||
|
||||
int
|
||||
telnet_spin()
|
||||
{
|
||||
ttloop();
|
||||
return(0);
|
||||
}
|
||||
|
||||
char *
|
||||
telnet_getenv(val)
|
||||
char *val;
|
||||
{
|
||||
extern char *getenv();
|
||||
return(getenv(val));
|
||||
}
|
||||
|
||||
char *
|
||||
telnet_gets(prompt, result, length, echo)
|
||||
char *prompt;
|
||||
char *result;
|
||||
int length;
|
||||
int echo;
|
||||
{
|
||||
return((char *)0);
|
||||
}
|
||||
#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
|
296
contrib/telnet/telnetd/defs.h
Normal file
296
contrib/telnet/telnetd/defs.h
Normal file
@ -0,0 +1,296 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifndef BSD
|
||||
# define BSD 43
|
||||
#endif
|
||||
|
||||
#if defined(CRAY) && !defined(LINEMODE)
|
||||
# define SYSV_TERMIO
|
||||
# define LINEMODE
|
||||
# define KLUDGELINEMODE
|
||||
# define DIAGNOSTICS
|
||||
# if defined(UNICOS50) && !defined(UNICOS5)
|
||||
# define UNICOS5
|
||||
# endif
|
||||
# if !defined(UNICOS5)
|
||||
# define BFTPDAEMON
|
||||
# define HAS_IP_TOS
|
||||
# endif
|
||||
#endif /* CRAY */
|
||||
#if defined(UNICOS5) && !defined(NO_SETSID)
|
||||
# define NO_SETSID
|
||||
#endif
|
||||
|
||||
#if defined(PRINTOPTIONS) && defined(DIAGNOSTICS)
|
||||
#define TELOPTS
|
||||
#define TELCMDS
|
||||
#define SLC_NAMES
|
||||
#endif
|
||||
|
||||
#if defined(SYSV_TERMIO) && !defined(USE_TERMIO)
|
||||
# define USE_TERMIO
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
#ifndef CRAY
|
||||
#include <sys/wait.h>
|
||||
#endif /* CRAY */
|
||||
#include <fcntl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#ifndef FILIO_H
|
||||
#include <sys/ioctl.h>
|
||||
#else
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <arpa/telnet.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef __STDC__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <syslog.h>
|
||||
#ifndef LOG_DAEMON
|
||||
#define LOG_DAEMON 0
|
||||
#endif
|
||||
#ifndef LOG_ODELAY
|
||||
#define LOG_ODELAY 0
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#ifndef NO_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifndef USE_TERMIO
|
||||
#include <sgtty.h>
|
||||
#else
|
||||
# ifdef SYSV_TERMIO
|
||||
# include <termio.h>
|
||||
# else
|
||||
# include <termios.h>
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(USE_TERMIO) || defined(NO_CC_T)
|
||||
typedef unsigned char cc_t;
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX_VDISABLE
|
||||
# ifdef VDISABLE
|
||||
# define _POSIX_VDISABLE VDISABLE
|
||||
# else
|
||||
# define _POSIX_VDISABLE ((unsigned char)'\377')
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CRAY
|
||||
# ifdef CRAY1
|
||||
# include <sys/pty.h>
|
||||
# ifndef FD_ZERO
|
||||
# include <sys/select.h>
|
||||
# endif /* FD_ZERO */
|
||||
# endif /* CRAY1 */
|
||||
|
||||
#include <memory.h>
|
||||
#endif /* CRAY */
|
||||
|
||||
#ifdef __hpux
|
||||
#include <sys/ptyio.h>
|
||||
#endif
|
||||
|
||||
#if !defined(TIOCSCTTY) && defined(TCSETCTTY)
|
||||
# define TIOCSCTTY TCSETCTTY
|
||||
#endif
|
||||
|
||||
#ifndef FD_SET
|
||||
#ifndef HAVE_fd_set
|
||||
typedef struct fd_set { int fds_bits[1]; } fd_set;
|
||||
#endif
|
||||
|
||||
#define FD_SET(n, p) ((p)->fds_bits[0] |= (1<<(n)))
|
||||
#define FD_CLR(n, p) ((p)->fds_bits[0] &= ~(1<<(n)))
|
||||
#define FD_ISSET(n, p) ((p)->fds_bits[0] & (1<<(n)))
|
||||
#define FD_ZERO(p) ((p)->fds_bits[0] = 0)
|
||||
#endif /* FD_SET */
|
||||
|
||||
/*
|
||||
* I/O data buffers defines
|
||||
*/
|
||||
#define NETSLOP 64
|
||||
#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)
|
||||
|
||||
/*
|
||||
* Linemode support states, in decreasing order of importance
|
||||
*/
|
||||
#define REAL_LINEMODE 0x04
|
||||
#define KLUDGE_OK 0x03
|
||||
#define NO_AUTOKLUDGE 0x02
|
||||
#define KLUDGE_LINEMODE 0x01
|
||||
#define NO_LINEMODE 0x00
|
||||
|
||||
/*
|
||||
* Structures of information for each special character function.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char flag; /* the flags for this function */
|
||||
cc_t val; /* the value of the special character */
|
||||
} slcent, *Slcent;
|
||||
|
||||
typedef struct {
|
||||
slcent defset; /* the default settings */
|
||||
slcent current; /* the current settings */
|
||||
cc_t *sptr; /* a pointer to the char in */
|
||||
/* system data structures */
|
||||
} slcfun, *Slcfun;
|
||||
|
||||
#ifdef DIAGNOSTICS
|
||||
/*
|
||||
* Diagnostics capabilities
|
||||
*/
|
||||
#define TD_REPORT 0x01 /* Report operations to client */
|
||||
#define TD_EXERCISE 0x02 /* Exercise client's implementation */
|
||||
#define TD_NETDATA 0x04 /* Display received data stream */
|
||||
#define TD_PTYDATA 0x08 /* Display data passed to pty */
|
||||
#define TD_OPTIONS 0x10 /* Report just telnet options */
|
||||
#endif /* DIAGNOSTICS */
|
||||
|
||||
/*
|
||||
* We keep track of each side of the option negotiation.
|
||||
*/
|
||||
|
||||
#define MY_STATE_WILL 0x01
|
||||
#define MY_WANT_STATE_WILL 0x02
|
||||
#define MY_STATE_DO 0x04
|
||||
#define MY_WANT_STATE_DO 0x08
|
||||
|
||||
/*
|
||||
* Macros to check the current state of things
|
||||
*/
|
||||
|
||||
#define my_state_is_do(opt) (options[opt]&MY_STATE_DO)
|
||||
#define my_state_is_will(opt) (options[opt]&MY_STATE_WILL)
|
||||
#define my_want_state_is_do(opt) (options[opt]&MY_WANT_STATE_DO)
|
||||
#define my_want_state_is_will(opt) (options[opt]&MY_WANT_STATE_WILL)
|
||||
|
||||
#define my_state_is_dont(opt) (!my_state_is_do(opt))
|
||||
#define my_state_is_wont(opt) (!my_state_is_will(opt))
|
||||
#define my_want_state_is_dont(opt) (!my_want_state_is_do(opt))
|
||||
#define my_want_state_is_wont(opt) (!my_want_state_is_will(opt))
|
||||
|
||||
#define set_my_state_do(opt) (options[opt] |= MY_STATE_DO)
|
||||
#define set_my_state_will(opt) (options[opt] |= MY_STATE_WILL)
|
||||
#define set_my_want_state_do(opt) (options[opt] |= MY_WANT_STATE_DO)
|
||||
#define set_my_want_state_will(opt) (options[opt] |= MY_WANT_STATE_WILL)
|
||||
|
||||
#define set_my_state_dont(opt) (options[opt] &= ~MY_STATE_DO)
|
||||
#define set_my_state_wont(opt) (options[opt] &= ~MY_STATE_WILL)
|
||||
#define set_my_want_state_dont(opt) (options[opt] &= ~MY_WANT_STATE_DO)
|
||||
#define set_my_want_state_wont(opt) (options[opt] &= ~MY_WANT_STATE_WILL)
|
||||
|
||||
/*
|
||||
* Tricky code here. What we want to know is if the MY_STATE_WILL
|
||||
* and MY_WANT_STATE_WILL bits have the same value. Since the two
|
||||
* bits are adjacent, a little arithmatic 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 symetrical
|
||||
*/
|
||||
|
||||
#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
|
240
contrib/telnet/telnetd/ext.h
Normal file
240
contrib/telnet/telnetd/ext.h
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Telnet server variable declarations
|
||||
*/
|
||||
extern char options[256];
|
||||
extern char do_dont_resp[256];
|
||||
extern char will_wont_resp[256];
|
||||
extern int linemode; /* linemode on/off */
|
||||
#ifdef LINEMODE
|
||||
extern int uselinemode; /* what linemode to use (on/off) */
|
||||
extern int editmode; /* edit modes in use */
|
||||
extern int useeditmode; /* edit modes to use */
|
||||
extern int alwayslinemode; /* command line option */
|
||||
# ifdef KLUDGELINEMODE
|
||||
extern int lmodetype; /* Client support for linemode */
|
||||
# endif /* KLUDGELINEMODE */
|
||||
#endif /* LINEMODE */
|
||||
extern int flowmode; /* current flow control state */
|
||||
extern int restartany; /* restart output on any character state */
|
||||
#ifdef DIAGNOSTICS
|
||||
extern int diagnostic; /* telnet diagnostic capabilities */
|
||||
#endif /* DIAGNOSTICS */
|
||||
#ifdef BFTPDAEMON
|
||||
extern int bftpd; /* behave as bftp daemon */
|
||||
#endif /* BFTPDAEMON */
|
||||
#if defined(SecurID)
|
||||
extern int require_SecurID;
|
||||
#endif
|
||||
#if defined(AUTHENTICATION)
|
||||
extern int auth_level;
|
||||
#endif
|
||||
|
||||
extern slcfun slctab[NSLC + 1]; /* slc mapping table */
|
||||
|
||||
char *terminaltype;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
#if defined(CRAY2) && defined(UNICOS5)
|
||||
extern int unpcc; /* characters left unprocessed by CRAY-2 terminal routine */
|
||||
extern char *unptyip; /* pointer to remaining characters in buffer */
|
||||
#endif
|
||||
|
||||
extern int pty, net;
|
||||
extern char *line;
|
||||
extern int SYNCHing; /* we are in TELNET SYNCH mode */
|
||||
|
||||
#ifndef P
|
||||
# ifdef __STDC__
|
||||
# define P(x) x
|
||||
# else
|
||||
# define P(x) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
extern void
|
||||
_termstat P((void)),
|
||||
add_slc P((int, int, int)),
|
||||
check_slc P((void)),
|
||||
change_slc P((int, int, int)),
|
||||
cleanup P((int)),
|
||||
clientstat P((int, int, int)),
|
||||
copy_termbuf P((char *, int)),
|
||||
deferslc P((void)),
|
||||
defer_terminit P((void)),
|
||||
do_opt_slc P((unsigned char *, int)),
|
||||
doeof P((void)),
|
||||
dooption P((int)),
|
||||
dontoption P((int)),
|
||||
edithost P((char *, char *)),
|
||||
fatal P((int, char *)),
|
||||
fatalperror P((int, char *)),
|
||||
get_slc_defaults P((void)),
|
||||
init_env P((void)),
|
||||
init_termbuf P((void)),
|
||||
interrupt P((void)),
|
||||
localstat P((void)),
|
||||
flowstat P((void)),
|
||||
netclear P((void)),
|
||||
netflush P((void)),
|
||||
#ifdef DIAGNOSTICS
|
||||
printoption P((char *, int)),
|
||||
printdata P((char *, char *, int)),
|
||||
printsub P((int, unsigned char *, int)),
|
||||
#endif
|
||||
ptyflush P((void)),
|
||||
putchr P((int)),
|
||||
putf P((char *, char *)),
|
||||
recv_ayt P((void)),
|
||||
send_do P((int, int)),
|
||||
send_dont P((int, int)),
|
||||
send_slc P((void)),
|
||||
send_status P((void)),
|
||||
send_will P((int, int)),
|
||||
send_wont P((int, int)),
|
||||
sendbrk P((void)),
|
||||
sendsusp P((void)),
|
||||
set_termbuf P((void)),
|
||||
start_login P((char *, int, char *)),
|
||||
start_slc P((int)),
|
||||
#if defined(AUTHENTICATION)
|
||||
start_slave P((char *)),
|
||||
#else
|
||||
start_slave P((char *, int, char *)),
|
||||
#endif
|
||||
suboption P((void)),
|
||||
telrcv P((void)),
|
||||
ttloop P((void)),
|
||||
tty_binaryin P((int)),
|
||||
tty_binaryout P((int));
|
||||
|
||||
extern int
|
||||
end_slc P((unsigned char **)),
|
||||
getnpty P((void)),
|
||||
#ifndef convex
|
||||
getpty P((int *)),
|
||||
#endif
|
||||
login_tty P((int)),
|
||||
spcset P((int, cc_t *, cc_t **)),
|
||||
stilloob P((int)),
|
||||
terminit P((void)),
|
||||
termstat P((void)),
|
||||
tty_flowmode P((void)),
|
||||
tty_restartany P((void)),
|
||||
tty_isbinaryin P((void)),
|
||||
tty_isbinaryout P((void)),
|
||||
tty_iscrnl P((void)),
|
||||
tty_isecho P((void)),
|
||||
tty_isediting P((void)),
|
||||
tty_islitecho P((void)),
|
||||
tty_isnewmap P((void)),
|
||||
tty_israw P((void)),
|
||||
tty_issofttab P((void)),
|
||||
tty_istrapsig P((void)),
|
||||
tty_linemode P((void));
|
||||
|
||||
extern void
|
||||
tty_rspeed P((int)),
|
||||
tty_setecho P((int)),
|
||||
tty_setedit P((int)),
|
||||
tty_setlinemode P((int)),
|
||||
tty_setlitecho P((int)),
|
||||
tty_setsig P((int)),
|
||||
tty_setsofttab P((int)),
|
||||
tty_tspeed P((int)),
|
||||
willoption P((int)),
|
||||
wontoption P((int)),
|
||||
writenet P((unsigned char *, int));
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
extern void (*encrypt_output) P((unsigned char *, int));
|
||||
extern int (*decrypt_input) P((int));
|
||||
extern char *nclearto;
|
||||
#endif /* ENCRYPTION */
|
||||
|
||||
|
||||
/*
|
||||
* The following are some clocks used to decide how to interpret
|
||||
* the relationship between various variables.
|
||||
*/
|
||||
|
||||
extern struct {
|
||||
int
|
||||
system, /* what the current time is */
|
||||
echotoggle, /* last time user entered echo character */
|
||||
modenegotiated, /* last time operating mode negotiated */
|
||||
didnetreceive, /* last time we read data from network */
|
||||
ttypesubopt, /* ttype subopt is received */
|
||||
tspeedsubopt, /* tspeed subopt is received */
|
||||
environsubopt, /* environ subopt is received */
|
||||
oenvironsubopt, /* old environ subopt is received */
|
||||
xdisplocsubopt, /* xdisploc subopt is received */
|
||||
baseline, /* time started to do timed action */
|
||||
gotDM; /* when did we last see a data mark */
|
||||
} clocks;
|
||||
|
||||
|
||||
#if defined(CRAY2) && defined(UNICOS5)
|
||||
extern int needtermstat;
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_IM
|
||||
# ifdef CRAY
|
||||
# define DEFAULT_IM "\r\n\r\nCray UNICOS (%h) (%t)\r\n\r\r\n\r"
|
||||
# else
|
||||
# ifdef sun
|
||||
# define DEFAULT_IM "\r\n\r\nSunOS UNIX (%h) (%t)\r\n\r\r\n\r"
|
||||
# else
|
||||
# ifdef ultrix
|
||||
# define DEFAULT_IM "\r\n\r\nULTRIX (%h) (%t)\r\n\r\r\n\r"
|
||||
# else
|
||||
# define DEFAULT_IM "\r\n\r\n4.4 BSD UNIX (%h) (%t)\r\n\r\r\n\r"
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
48
contrib/telnet/telnetd/global.c
Normal file
48
contrib/telnet/telnetd/global.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)global.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* Allocate global variables. We do this
|
||||
* by including the header file that defines
|
||||
* them all as externs, but first we define
|
||||
* the keyword "extern" to be nothing, so that
|
||||
* we will actually allocate the space.
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
#define extern
|
||||
#include "ext.h"
|
55
contrib/telnet/telnetd/pathnames.h
Normal file
55
contrib/telnet/telnetd/pathnames.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* @(#)pathnames.h 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
|
||||
#if BSD > 43
|
||||
|
||||
# include <paths.h>
|
||||
|
||||
# ifndef _PATH_LOGIN
|
||||
# define _PATH_LOGIN "/usr/bin/login"
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
# define _PATH_TTY "/dev/tty"
|
||||
# ifndef _PATH_LOGIN
|
||||
# define _PATH_LOGIN "/bin/login"
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BFTPDAEMON
|
||||
#define BFTPPATH "/usr/ucb/bftp"
|
||||
#endif /* BFTPDAEMON */
|
491
contrib/telnet/telnetd/slc.c
Normal file
491
contrib/telnet/telnetd/slc.c
Normal file
@ -0,0 +1,491 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)slc.c 8.2 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "telnetd.h"
|
||||
|
||||
#ifdef LINEMODE
|
||||
/*
|
||||
* local varibles
|
||||
*/
|
||||
static unsigned char *def_slcbuf = (unsigned char *)0;
|
||||
static int def_slclen = 0;
|
||||
static int slcchange; /* change to slc is requested */
|
||||
static unsigned char *slcptr; /* pointer into slc buffer */
|
||||
static unsigned char slcbuf[NSLC*6]; /* buffer for slc negotiation */
|
||||
|
||||
/*
|
||||
* send_slc
|
||||
*
|
||||
* Write out the current special characters to the client.
|
||||
*/
|
||||
void
|
||||
send_slc()
|
||||
{
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* Send out list of triplets of special characters
|
||||
* to client. We only send info on the characters
|
||||
* that are currently supported.
|
||||
*/
|
||||
for (i = 1; i <= NSLC; i++) {
|
||||
if ((slctab[i].defset.flag & SLC_LEVELBITS) == SLC_NOSUPPORT)
|
||||
continue;
|
||||
add_slc((unsigned char)i, slctab[i].current.flag,
|
||||
slctab[i].current.val);
|
||||
}
|
||||
|
||||
} /* end of send_slc */
|
||||
|
||||
/*
|
||||
* default_slc
|
||||
*
|
||||
* Set pty special characters to all the defaults.
|
||||
*/
|
||||
void
|
||||
default_slc()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 1; i <= NSLC; i++) {
|
||||
slctab[i].current.val = slctab[i].defset.val;
|
||||
if (slctab[i].current.val == (cc_t)(_POSIX_VDISABLE))
|
||||
slctab[i].current.flag = SLC_NOSUPPORT;
|
||||
else
|
||||
slctab[i].current.flag = slctab[i].defset.flag;
|
||||
if (slctab[i].sptr) {
|
||||
*(slctab[i].sptr) = slctab[i].defset.val;
|
||||
}
|
||||
}
|
||||
slcchange = 1;
|
||||
|
||||
} /* end of default_slc */
|
||||
#endif /* LINEMODE */
|
||||
|
||||
/*
|
||||
* get_slc_defaults
|
||||
*
|
||||
* Initialize the slc mapping table.
|
||||
*/
|
||||
void
|
||||
get_slc_defaults()
|
||||
{
|
||||
register int i;
|
||||
|
||||
init_termbuf();
|
||||
|
||||
for (i = 1; i <= NSLC; i++) {
|
||||
slctab[i].defset.flag =
|
||||
spcset(i, &slctab[i].defset.val, &slctab[i].sptr);
|
||||
slctab[i].current.flag = SLC_NOSUPPORT;
|
||||
slctab[i].current.val = 0;
|
||||
}
|
||||
|
||||
} /* end of get_slc_defaults */
|
||||
|
||||
#ifdef LINEMODE
|
||||
/*
|
||||
* add_slc
|
||||
*
|
||||
* Add an slc triplet to the slc buffer.
|
||||
*/
|
||||
void
|
||||
add_slc(func, flag, val)
|
||||
register char func, flag;
|
||||
register cc_t val;
|
||||
{
|
||||
|
||||
if ((*slcptr++ = (unsigned char)func) == 0xff)
|
||||
*slcptr++ = 0xff;
|
||||
|
||||
if ((*slcptr++ = (unsigned char)flag) == 0xff)
|
||||
*slcptr++ = 0xff;
|
||||
|
||||
if ((*slcptr++ = (unsigned char)val) == 0xff)
|
||||
*slcptr++ = 0xff;
|
||||
|
||||
} /* end of add_slc */
|
||||
|
||||
/*
|
||||
* start_slc
|
||||
*
|
||||
* Get ready to process incoming slc's and respond to them.
|
||||
*
|
||||
* The parameter getit is non-zero if it is necessary to grab a copy
|
||||
* of the terminal control structures.
|
||||
*/
|
||||
void
|
||||
start_slc(getit)
|
||||
register int getit;
|
||||
{
|
||||
|
||||
slcchange = 0;
|
||||
if (getit)
|
||||
init_termbuf();
|
||||
(void) sprintf((char *)slcbuf, "%c%c%c%c",
|
||||
IAC, SB, TELOPT_LINEMODE, LM_SLC);
|
||||
slcptr = slcbuf + 4;
|
||||
|
||||
} /* end of start_slc */
|
||||
|
||||
/*
|
||||
* end_slc
|
||||
*
|
||||
* Finish up the slc negotiation. If something to send, then send it.
|
||||
*/
|
||||
int
|
||||
end_slc(bufp)
|
||||
register unsigned char **bufp;
|
||||
{
|
||||
register int len;
|
||||
void netflush();
|
||||
|
||||
/*
|
||||
* If a change has occured, store the new terminal control
|
||||
* structures back to the terminal driver.
|
||||
*/
|
||||
if (slcchange) {
|
||||
set_termbuf();
|
||||
}
|
||||
|
||||
/*
|
||||
* If the pty state has not yet been fully processed and there is a
|
||||
* deferred slc request from the client, then do not send any
|
||||
* sort of slc negotiation now. We will respond to the client's
|
||||
* request very soon.
|
||||
*/
|
||||
if (def_slcbuf && (terminit() == 0)) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (slcptr > (slcbuf + 4)) {
|
||||
if (bufp) {
|
||||
*bufp = &slcbuf[4];
|
||||
return(slcptr - slcbuf - 4);
|
||||
} else {
|
||||
(void) sprintf((char *)slcptr, "%c%c", IAC, SE);
|
||||
slcptr += 2;
|
||||
len = slcptr - slcbuf;
|
||||
writenet(slcbuf, len);
|
||||
netflush(); /* force it out immediately */
|
||||
DIAG(TD_OPTIONS, printsub('>', slcbuf+2, len-2););
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
|
||||
} /* end of end_slc */
|
||||
|
||||
/*
|
||||
* process_slc
|
||||
*
|
||||
* Figure out what to do about the client's slc
|
||||
*/
|
||||
void
|
||||
process_slc(func, flag, val)
|
||||
register unsigned char func, flag;
|
||||
register cc_t val;
|
||||
{
|
||||
register int hislevel, mylevel, ack;
|
||||
|
||||
/*
|
||||
* Ensure that we know something about this function
|
||||
*/
|
||||
if (func > NSLC) {
|
||||
add_slc(func, SLC_NOSUPPORT, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the special case requests of 0 SLC_DEFAULT 0
|
||||
* and 0 SLC_VARIABLE 0. Be a little forgiving here, don't
|
||||
* worry about whether the value is actually 0 or not.
|
||||
*/
|
||||
if (func == 0) {
|
||||
if ((flag = flag & SLC_LEVELBITS) == SLC_DEFAULT) {
|
||||
default_slc();
|
||||
send_slc();
|
||||
} else if (flag == SLC_VARIABLE) {
|
||||
send_slc();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Appears to be a function that we know something about. So
|
||||
* get on with it and see what we know.
|
||||
*/
|
||||
|
||||
hislevel = flag & SLC_LEVELBITS;
|
||||
mylevel = slctab[func].current.flag & SLC_LEVELBITS;
|
||||
ack = flag & SLC_ACK;
|
||||
/*
|
||||
* ignore the command if:
|
||||
* the function value and level are the same as what we already have;
|
||||
* or the level is the same and the ack bit is set
|
||||
*/
|
||||
if (hislevel == mylevel && (val == slctab[func].current.val || ack)) {
|
||||
return;
|
||||
} else if (ack) {
|
||||
/*
|
||||
* If we get here, we got an ack, but the levels don't match.
|
||||
* This shouldn't happen. If it does, it is probably because
|
||||
* we have sent two requests to set a variable without getting
|
||||
* a response between them, and this is the first response.
|
||||
* So, ignore it, and wait for the next response.
|
||||
*/
|
||||
return;
|
||||
} else {
|
||||
change_slc(func, flag, val);
|
||||
}
|
||||
|
||||
} /* end of process_slc */
|
||||
|
||||
/*
|
||||
* change_slc
|
||||
*
|
||||
* Process a request to change one of our special characters.
|
||||
* Compare client's request with what we are capable of supporting.
|
||||
*/
|
||||
void
|
||||
change_slc(func, flag, val)
|
||||
register char func, flag;
|
||||
register cc_t val;
|
||||
{
|
||||
register int hislevel, mylevel;
|
||||
|
||||
hislevel = flag & SLC_LEVELBITS;
|
||||
mylevel = slctab[func].defset.flag & SLC_LEVELBITS;
|
||||
/*
|
||||
* If client is setting a function to NOSUPPORT
|
||||
* or DEFAULT, then we can easily and directly
|
||||
* accomodate the request.
|
||||
*/
|
||||
if (hislevel == SLC_NOSUPPORT) {
|
||||
slctab[func].current.flag = flag;
|
||||
slctab[func].current.val = (cc_t)_POSIX_VDISABLE;
|
||||
flag |= SLC_ACK;
|
||||
add_slc(func, flag, val);
|
||||
return;
|
||||
}
|
||||
if (hislevel == SLC_DEFAULT) {
|
||||
/*
|
||||
* Special case here. If client tells us to use
|
||||
* the default on a function we don't support, then
|
||||
* return NOSUPPORT instead of what we may have as a
|
||||
* default level of DEFAULT.
|
||||
*/
|
||||
if (mylevel == SLC_DEFAULT) {
|
||||
slctab[func].current.flag = SLC_NOSUPPORT;
|
||||
} else {
|
||||
slctab[func].current.flag = slctab[func].defset.flag;
|
||||
}
|
||||
slctab[func].current.val = slctab[func].defset.val;
|
||||
add_slc(func, slctab[func].current.flag,
|
||||
slctab[func].current.val);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Client wants us to change to a new value or he
|
||||
* is telling us that he can't change to our value.
|
||||
* Some of the slc's we support and can change,
|
||||
* some we do support but can't change,
|
||||
* and others we don't support at all.
|
||||
* If we can change it then we have a pointer to
|
||||
* the place to put the new value, so change it,
|
||||
* otherwise, continue the negotiation.
|
||||
*/
|
||||
if (slctab[func].sptr) {
|
||||
/*
|
||||
* We can change this one.
|
||||
*/
|
||||
slctab[func].current.val = val;
|
||||
*(slctab[func].sptr) = val;
|
||||
slctab[func].current.flag = flag;
|
||||
flag |= SLC_ACK;
|
||||
slcchange = 1;
|
||||
add_slc(func, flag, val);
|
||||
} else {
|
||||
/*
|
||||
* It is not possible for us to support this
|
||||
* request as he asks.
|
||||
*
|
||||
* If our level is DEFAULT, then just ack whatever was
|
||||
* sent.
|
||||
*
|
||||
* If he can't change and we can't change,
|
||||
* then degenerate to NOSUPPORT.
|
||||
*
|
||||
* Otherwise we send our level back to him, (CANTCHANGE
|
||||
* or NOSUPPORT) and if CANTCHANGE, send
|
||||
* our value as well.
|
||||
*/
|
||||
if (mylevel == SLC_DEFAULT) {
|
||||
slctab[func].current.flag = flag;
|
||||
slctab[func].current.val = val;
|
||||
flag |= SLC_ACK;
|
||||
} else if (hislevel == SLC_CANTCHANGE &&
|
||||
mylevel == SLC_CANTCHANGE) {
|
||||
flag &= ~SLC_LEVELBITS;
|
||||
flag |= SLC_NOSUPPORT;
|
||||
slctab[func].current.flag = flag;
|
||||
} else {
|
||||
flag &= ~SLC_LEVELBITS;
|
||||
flag |= mylevel;
|
||||
slctab[func].current.flag = flag;
|
||||
if (mylevel == SLC_CANTCHANGE) {
|
||||
slctab[func].current.val =
|
||||
slctab[func].defset.val;
|
||||
val = slctab[func].current.val;
|
||||
}
|
||||
}
|
||||
add_slc(func, flag, val);
|
||||
}
|
||||
|
||||
} /* end of change_slc */
|
||||
|
||||
#if defined(USE_TERMIO) && (VEOF == VMIN)
|
||||
cc_t oldeofc = '\004';
|
||||
#endif
|
||||
|
||||
/*
|
||||
* check_slc
|
||||
*
|
||||
* Check the special characters in use and notify the client if any have
|
||||
* changed. Only those characters that are capable of being changed are
|
||||
* likely to have changed. If a local change occurs, kick the support level
|
||||
* and flags up to the defaults.
|
||||
*/
|
||||
void
|
||||
check_slc()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 1; i <= NSLC; i++) {
|
||||
#if defined(USE_TERMIO) && (VEOF == VMIN)
|
||||
/*
|
||||
* In a perfect world this would be a neat little
|
||||
* function. But in this world, we should not notify
|
||||
* client of changes to the VEOF char when
|
||||
* ICANON is off, because it is not representing
|
||||
* a special character.
|
||||
*/
|
||||
if (i == SLC_EOF) {
|
||||
if (!tty_isediting())
|
||||
continue;
|
||||
else if (slctab[i].sptr)
|
||||
oldeofc = *(slctab[i].sptr);
|
||||
}
|
||||
#endif /* defined(USE_TERMIO) && defined(SYSV_TERMIO) */
|
||||
if (slctab[i].sptr &&
|
||||
(*(slctab[i].sptr) != slctab[i].current.val)) {
|
||||
slctab[i].current.val = *(slctab[i].sptr);
|
||||
if (*(slctab[i].sptr) == (cc_t)_POSIX_VDISABLE)
|
||||
slctab[i].current.flag = SLC_NOSUPPORT;
|
||||
else
|
||||
slctab[i].current.flag = slctab[i].defset.flag;
|
||||
add_slc((unsigned char)i, slctab[i].current.flag,
|
||||
slctab[i].current.val);
|
||||
}
|
||||
}
|
||||
} /* check_slc */
|
||||
|
||||
/*
|
||||
* do_opt_slc
|
||||
*
|
||||
* Process an slc option buffer. Defer processing of incoming slc's
|
||||
* until after the terminal state has been processed. Save the first slc
|
||||
* request that comes along, but discard all others.
|
||||
*
|
||||
* ptr points to the beginning of the buffer, len is the length.
|
||||
*/
|
||||
void
|
||||
do_opt_slc(ptr, len)
|
||||
register unsigned char *ptr;
|
||||
register int len;
|
||||
{
|
||||
register unsigned char func, flag;
|
||||
cc_t val;
|
||||
register unsigned char *end = ptr + len;
|
||||
|
||||
if (terminit()) { /* go ahead */
|
||||
while (ptr < end) {
|
||||
func = *ptr++;
|
||||
if (ptr >= end) break;
|
||||
flag = *ptr++;
|
||||
if (ptr >= end) break;
|
||||
val = (cc_t)*ptr++;
|
||||
|
||||
process_slc(func, flag, val);
|
||||
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* save this slc buffer if it is the first, otherwise dump
|
||||
* it.
|
||||
*/
|
||||
if (def_slcbuf == (unsigned char *)0) {
|
||||
def_slclen = len;
|
||||
def_slcbuf = (unsigned char *)malloc((unsigned)len);
|
||||
if (def_slcbuf == (unsigned char *)0)
|
||||
return; /* too bad */
|
||||
memmove(def_slcbuf, ptr, len);
|
||||
}
|
||||
}
|
||||
|
||||
} /* end of do_opt_slc */
|
||||
|
||||
/*
|
||||
* deferslc
|
||||
*
|
||||
* Do slc stuff that was deferred.
|
||||
*/
|
||||
void
|
||||
deferslc()
|
||||
{
|
||||
if (def_slcbuf) {
|
||||
start_slc(1);
|
||||
do_opt_slc(def_slcbuf, def_slclen);
|
||||
(void) end_slc(0);
|
||||
free(def_slcbuf);
|
||||
def_slcbuf = (unsigned char *)0;
|
||||
def_slclen = 0;
|
||||
}
|
||||
|
||||
} /* end of deferslc */
|
||||
|
||||
#endif /* LINEMODE */
|
1612
contrib/telnet/telnetd/state.c
Normal file
1612
contrib/telnet/telnetd/state.c
Normal file
File diff suppressed because it is too large
Load Diff
2303
contrib/telnet/telnetd/sys_term.c
Normal file
2303
contrib/telnet/telnetd/sys_term.c
Normal file
File diff suppressed because it is too large
Load Diff
607
contrib/telnet/telnetd/telnetd.8
Normal file
607
contrib/telnet/telnetd/telnetd.8
Normal file
@ -0,0 +1,607 @@
|
||||
.\" 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. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. 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 BSD 4.2
|
||||
.Sh NAME
|
||||
.Nm telnetd
|
||||
.Nd DARPA
|
||||
.Tn TELNET
|
||||
protocol server
|
||||
.Sh SYNOPSIS
|
||||
.Nm /usr/libexec/telnetd
|
||||
.Op Fl BUhlkns
|
||||
.Op Fl D Ar debugmode
|
||||
.Op Fl I Ns Ar initid
|
||||
.Op Fl S Ar tos
|
||||
.Op Fl X Ar authtype
|
||||
.Op Fl a Ar authmode
|
||||
.Op Fl edebug
|
||||
.Op Fl r Ns Ar lowpty-highpty
|
||||
.Op Fl u Ar len
|
||||
.Op Fl debug Op Ar port
|
||||
.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 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 authentication information
|
||||
to identify the remote user,
|
||||
and is allowed access to the specified account
|
||||
without providing a password.
|
||||
.It valid
|
||||
Only allow connections when the remote user
|
||||
can provide valid authentication information
|
||||
to identify the remote user.
|
||||
The
|
||||
.Xr login 1
|
||||
command will provide any additional user verification
|
||||
needed if the remote user is not allowed automatic
|
||||
access to the specified account.
|
||||
.It other
|
||||
Only allow connections that supply some authentication information.
|
||||
This option is currently not supported
|
||||
by any of the existing authentication mechanisms,
|
||||
and is thus the same as specifying
|
||||
.Fl a
|
||||
.Cm valid .
|
||||
.It none
|
||||
This is the default state.
|
||||
Authentication information is not required.
|
||||
If no or insufficient authentication information
|
||||
is provided, then the
|
||||
.Xr login 1
|
||||
program will provide the necessary user
|
||||
verification.
|
||||
.It off
|
||||
This disables the authentication code.
|
||||
All user verification will happen through the
|
||||
.Xr login 1
|
||||
program.
|
||||
.El
|
||||
.It Fl B
|
||||
Specifies bftp server mode. In this mode,
|
||||
.Nm telnetd
|
||||
causes login to start a
|
||||
.Xr bftp 1
|
||||
session rather than the user's
|
||||
normal shell. In bftp daemon mode normal
|
||||
logins are not supported, and it must be used
|
||||
on a port other than the normal
|
||||
.Tn TELNET
|
||||
port.
|
||||
.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 debug
|
||||
Enables debugging on each socket created by
|
||||
.Nm telnetd
|
||||
(see
|
||||
.Dv SO_DEBUG
|
||||
in
|
||||
.Xr socket 2 ) .
|
||||
.It Fl edebug
|
||||
If
|
||||
.Nm telnetd
|
||||
has been compiled with support for data encryption, then the
|
||||
.Fl edebug
|
||||
option may be used to enable encryption debugging code.
|
||||
.It Fl h
|
||||
Disables the printing of host-specific information before
|
||||
login has been completed.
|
||||
.It Fl I Ar initid
|
||||
This option is only applicable to
|
||||
.Tn UNICOS
|
||||
systems prior to 7.0.
|
||||
It specifies the
|
||||
.Dv ID
|
||||
from
|
||||
.Pa /etc/inittab
|
||||
to use when init starts login sessions. The default
|
||||
.Dv ID
|
||||
is
|
||||
.Dv fe.
|
||||
.It Fl k
|
||||
This option is only useful if
|
||||
.Nm telnetd
|
||||
has been compiled with both linemode and kludge linemode
|
||||
support. If the
|
||||
.Fl k
|
||||
option is specified, then if the remote client does not
|
||||
support the
|
||||
.Dv LINEMODE
|
||||
option, then
|
||||
.Nm telnetd
|
||||
will operate in character at a time mode.
|
||||
It will still support kludge linemode, but will only
|
||||
go into kludge linemode if the remote client requests
|
||||
it.
|
||||
(This is done by by the client sending
|
||||
.Dv DONT SUPPRESS-GO-AHEAD
|
||||
and
|
||||
.Dv DONT ECHO . )
|
||||
The
|
||||
.Fl k
|
||||
option is most useful when there are remote clients
|
||||
that do not support kludge linemode, but pass the heuristic
|
||||
(if they respond with
|
||||
.Dv WILL TIMING-MARK
|
||||
in response to a
|
||||
.Dv DO TIMING-MARK)
|
||||
for kludge linemode support.
|
||||
.It Fl l
|
||||
Specifies line mode. Tries to force clients to use line-
|
||||
at-a-time mode.
|
||||
If the
|
||||
.Dv LINEMODE
|
||||
option is not supported, it will go
|
||||
into kludge linemode.
|
||||
.It Fl n
|
||||
Disable
|
||||
.Dv TCP
|
||||
keep-alives. Normally
|
||||
.Nm 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 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
|
||||
This option is only enabled if
|
||||
.Nm telnetd
|
||||
is compiled with support for
|
||||
.Tn SecurID
|
||||
cards.
|
||||
It causes the
|
||||
.Fl s
|
||||
option to be passed on to
|
||||
.Xr login 1 ,
|
||||
and thus is only useful if
|
||||
.Xr login 1
|
||||
supports the
|
||||
.Fl s
|
||||
flag to indicate that only
|
||||
.Tn SecurID
|
||||
validated logins are allowed, and is
|
||||
usually useful for controlling remote logins
|
||||
from outside of a firewall.
|
||||
.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.
|
||||
.ne 1i
|
||||
.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 .
|
||||
.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 \*(lqcooked\*(rq 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
|
||||
.Tn telnetd
|
||||
will take care of echoing any data that needs to be
|
||||
echoed to the terminal, and then nothing is echoed.
|
||||
When terminal echo is desired, a
|
||||
.Dv WONT ECHO
|
||||
is sent to indicate that
|
||||
.Tn telnetd
|
||||
will not be doing any terminal echoing, so the
|
||||
client should do any terminal echoing that is needed.
|
||||
.It "WILL BINARY"
|
||||
Indicates that the client is willing to send a
|
||||
8 bits of data, rather than the normal 7 bits
|
||||
of the Network Virtual Terminal.
|
||||
.It "WILL SGA"
|
||||
Indicates that it will not be sending
|
||||
.Dv IAC GA,
|
||||
go ahead, commands.
|
||||
.It "WILL STATUS"
|
||||
Indicates a willingness to send the client, upon
|
||||
request, of the current status of all
|
||||
.Tn TELNET
|
||||
options.
|
||||
.It "WILL TIMING-MARK"
|
||||
Whenever a
|
||||
.Dv DO TIMING-MARK
|
||||
command is received, it is always responded
|
||||
to with a
|
||||
.Dv WILL TIMING-MARK
|
||||
.ne 1i
|
||||
.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
|
||||
is compiled with support for data encryption, 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
|
||||
.Tn telnetd
|
||||
is willing to receive an 8 bit data stream.
|
||||
.It "DO LFLOW"
|
||||
Requests that the client handle flow control
|
||||
characters remotely.
|
||||
.It "DO ECHO"
|
||||
This is not really supported, but is sent to identify a 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 X windows display that is associated with
|
||||
the telnet client.
|
||||
.It "DO NEW-ENVIRON"
|
||||
Indicates a desire to be able to request environment
|
||||
variable information, as described in RFC 1572.
|
||||
.It "DO ENVIRON"
|
||||
Indicates a desire to be able to request environment
|
||||
variable information, as described in RFC 1408.
|
||||
.It "DO LINEMODE"
|
||||
Only sent if
|
||||
.Nm 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
|
||||
is compiled with support for authentication, and
|
||||
indicates a willingness to receive authentication
|
||||
information for automatic login.
|
||||
.It "DO ENCRYPT"
|
||||
Only sent if
|
||||
.Nm telnetd
|
||||
is compiled with support for data encryption, and
|
||||
indicates a willingness to decrypt
|
||||
the data stream.
|
||||
.Sh ENVIRONMENT
|
||||
.Sh FILES
|
||||
.Pa /etc/services
|
||||
.br
|
||||
.Pa /etc/inittab
|
||||
(UNICOS systems only)
|
||||
.br
|
||||
.Pa /etc/iptos
|
||||
(if supported)
|
||||
.br
|
||||
.Pa /usr/ucb/bftp
|
||||
(if supported)
|
||||
.Sh "SEE ALSO"
|
||||
.Xr telnet 1 ,
|
||||
.Xr login 1 ,
|
||||
.Xr bftp 1
|
||||
(if supported)
|
||||
.Sh STANDARDS
|
||||
.Bl -tag -compact -width RFC-1572
|
||||
.It Cm RFC-854
|
||||
.Tn TELNET
|
||||
PROTOCOL SPECIFICATION
|
||||
.It Cm RFC-855
|
||||
TELNET OPTION SPECIFICATIONS
|
||||
.It Cm RFC-856
|
||||
TELNET BINARY TRANSMISSION
|
||||
.It Cm RFC-857
|
||||
TELNET ECHO OPTION
|
||||
.It Cm RFC-858
|
||||
TELNET SUPPRESS GO AHEAD OPTION
|
||||
.It Cm RFC-859
|
||||
TELNET STATUS OPTION
|
||||
.It Cm RFC-860
|
||||
TELNET TIMING MARK OPTION
|
||||
.It Cm RFC-861
|
||||
TELNET EXTENDED OPTIONS - LIST OPTION
|
||||
.It Cm RFC-885
|
||||
TELNET END OF RECORD OPTION
|
||||
.It Cm RFC-1073
|
||||
Telnet Window Size Option
|
||||
.It Cm RFC-1079
|
||||
Telnet Terminal Speed Option
|
||||
.It Cm RFC-1091
|
||||
Telnet Terminal-Type Option
|
||||
.It Cm RFC-1096
|
||||
Telnet X Display Location Option
|
||||
.It Cm RFC-1123
|
||||
Requirements for Internet Hosts -- Application and Support
|
||||
.It Cm RFC-1184
|
||||
Telnet Linemode Option
|
||||
.It Cm RFC-1372
|
||||
Telnet Remote Flow Control Option
|
||||
.It Cm RFC-1416
|
||||
Telnet Authentication Option
|
||||
.It Cm RFC-1411
|
||||
Telnet Authentication: Kerberos Version 4
|
||||
.It Cm RFC-1412
|
||||
Telnet Authentication: SPX
|
||||
.It Cm RFC-1571
|
||||
Telnet Environment Option Interoperability Issues
|
||||
.It Cm RFC-1572
|
||||
Telnet Environment Option
|
||||
.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.
|
1608
contrib/telnet/telnetd/telnetd.c
Normal file
1608
contrib/telnet/telnetd/telnetd.c
Normal file
File diff suppressed because it is too large
Load Diff
49
contrib/telnet/telnetd/telnetd.h
Normal file
49
contrib/telnet/telnetd/telnetd.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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 "defs.h"
|
||||
#include "ext.h"
|
||||
|
||||
#ifdef DIAGNOSTICS
|
||||
#define DIAG(a,b) if (diagnostic & (a)) b
|
||||
#else
|
||||
#define DIAG(a,b)
|
||||
#endif
|
||||
|
||||
/* other external variables */
|
||||
extern char **environ;
|
||||
extern int errno;
|
||||
|
660
contrib/telnet/telnetd/termstat.c
Normal file
660
contrib/telnet/telnetd/termstat.c
Normal file
@ -0,0 +1,660 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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
|
||||
static char sccsid[] = "@(#)termstat.c 8.2 (Berkeley) 5/30/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "telnetd.h"
|
||||
|
||||
/*
|
||||
* local variables
|
||||
*/
|
||||
int def_tspeed = -1, def_rspeed = -1;
|
||||
#ifdef TIOCSWINSZ
|
||||
int def_row = 0, def_col = 0;
|
||||
#endif
|
||||
#ifdef LINEMODE
|
||||
static int _terminit = 0;
|
||||
#endif /* LINEMODE */
|
||||
|
||||
#if defined(CRAY2) && defined(UNICOS5)
|
||||
int newmap = 1; /* nonzero if \n maps to ^M^J */
|
||||
#endif
|
||||
|
||||
#ifdef LINEMODE
|
||||
/*
|
||||
* localstat
|
||||
*
|
||||
* This function handles all management of linemode.
|
||||
*
|
||||
* Linemode allows the client to do the local editing of data
|
||||
* and send only complete lines to the server. Linemode state is
|
||||
* based on the state of the pty driver. If the pty is set for
|
||||
* external processing, then we can use linemode. Further, if we
|
||||
* can use real linemode, then we can look at the edit control bits
|
||||
* in the pty to determine what editing the client should do.
|
||||
*
|
||||
* Linemode support uses the following state flags to keep track of
|
||||
* current and desired linemode state.
|
||||
* alwayslinemode : true if -l was specified on the telnetd
|
||||
* command line. It means to have linemode on as much as
|
||||
* possible.
|
||||
*
|
||||
* lmodetype: signifies whether the client can
|
||||
* handle real linemode, or if use of kludgeomatic linemode
|
||||
* is preferred. It will be set to one of the following:
|
||||
* REAL_LINEMODE : use linemode option
|
||||
* NO_KLUDGE : don't initiate kludge linemode.
|
||||
* KLUDGE_LINEMODE : use kludge linemode
|
||||
* NO_LINEMODE : client is ignorant of linemode
|
||||
*
|
||||
* linemode, uselinemode : linemode is true if linemode
|
||||
* is currently on, uselinemode is the state that we wish
|
||||
* to be in. If another function wishes to turn linemode
|
||||
* on or off, it sets or clears uselinemode.
|
||||
*
|
||||
* editmode, useeditmode : like linemode/uselinemode, but
|
||||
* these contain the edit mode states (edit and trapsig).
|
||||
*
|
||||
* The state variables correspond to some of the state information
|
||||
* in the pty.
|
||||
* linemode:
|
||||
* In real linemode, this corresponds to whether the pty
|
||||
* expects external processing of incoming data.
|
||||
* In kludge linemode, this more closely corresponds to the
|
||||
* whether normal processing is on or not. (ICANON in
|
||||
* system V, or COOKED mode in BSD.)
|
||||
* If the -l option was specified (alwayslinemode), then
|
||||
* an attempt is made to force external processing on at
|
||||
* all times.
|
||||
*
|
||||
* The following heuristics are applied to determine linemode
|
||||
* handling within the server.
|
||||
* 1) Early on in starting up the server, an attempt is made
|
||||
* to negotiate the linemode option. If this succeeds
|
||||
* then lmodetype is set to REAL_LINEMODE and all linemode
|
||||
* processing occurs in the context of the linemode option.
|
||||
* 2) If the attempt to negotiate the linemode option failed,
|
||||
* and the "-k" (don't initiate kludge linemode) isn't set,
|
||||
* then we try to use kludge linemode. We test for this
|
||||
* capability by sending "do Timing Mark". If a positive
|
||||
* response comes back, then we assume that the client
|
||||
* understands kludge linemode (ech!) and the
|
||||
* lmodetype flag is set to KLUDGE_LINEMODE.
|
||||
* 3) Otherwise, linemode is not supported at all and
|
||||
* lmodetype remains set to NO_LINEMODE (which happens
|
||||
* to be 0 for convenience).
|
||||
* 4) At any time a command arrives that implies a higher
|
||||
* state of linemode support in the client, we move to that
|
||||
* linemode support.
|
||||
*
|
||||
* A short explanation of kludge linemode is in order here.
|
||||
* 1) The heuristic to determine support for kludge linemode
|
||||
* is to send a do timing mark. We assume that a client
|
||||
* that supports timing marks also supports kludge linemode.
|
||||
* A risky proposition at best.
|
||||
* 2) Further negotiation of linemode is done by changing the
|
||||
* the server's state regarding SGA. If server will SGA,
|
||||
* then linemode is off, if server won't SGA, then linemode
|
||||
* is on.
|
||||
*/
|
||||
void
|
||||
localstat()
|
||||
{
|
||||
void netflush();
|
||||
int need_will_echo = 0;
|
||||
|
||||
#if defined(CRAY2) && defined(UNICOS5)
|
||||
/*
|
||||
* Keep track of that ol' CR/NL mapping while we're in the
|
||||
* neighborhood.
|
||||
*/
|
||||
newmap = tty_isnewmap();
|
||||
#endif /* defined(CRAY2) && defined(UNICOS5) */
|
||||
|
||||
/*
|
||||
* Check for state of BINARY options.
|
||||
*/
|
||||
if (tty_isbinaryin()) {
|
||||
if (his_want_state_is_wont(TELOPT_BINARY))
|
||||
send_do(TELOPT_BINARY, 1);
|
||||
} else {
|
||||
if (his_want_state_is_will(TELOPT_BINARY))
|
||||
send_dont(TELOPT_BINARY, 1);
|
||||
}
|
||||
|
||||
if (tty_isbinaryout()) {
|
||||
if (my_want_state_is_wont(TELOPT_BINARY))
|
||||
send_will(TELOPT_BINARY, 1);
|
||||
} else {
|
||||
if (my_want_state_is_will(TELOPT_BINARY))
|
||||
send_wont(TELOPT_BINARY, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for changes to flow control if client supports it.
|
||||
*/
|
||||
flowstat();
|
||||
|
||||
/*
|
||||
* Check linemode on/off state
|
||||
*/
|
||||
uselinemode = tty_linemode();
|
||||
|
||||
/*
|
||||
* If alwayslinemode is on, and pty is changing to turn it off, then
|
||||
* force linemode back on.
|
||||
*/
|
||||
if (alwayslinemode && linemode && !uselinemode) {
|
||||
uselinemode = 1;
|
||||
tty_setlinemode(uselinemode);
|
||||
}
|
||||
|
||||
#ifdef ENCRYPTION
|
||||
/*
|
||||
* If the terminal is not echoing, but editing is enabled,
|
||||
* something like password input is going to happen, so
|
||||
* if we the other side is not currently sending encrypted
|
||||
* data, ask the other side to start encrypting.
|
||||
*/
|
||||
if (his_state_is_will(TELOPT_ENCRYPT)) {
|
||||
static int enc_passwd = 0;
|
||||
if (uselinemode && !tty_isecho() && tty_isediting()
|
||||
&& (enc_passwd == 0) && !decrypt_input) {
|
||||
encrypt_send_request_start();
|
||||
enc_passwd = 1;
|
||||
} else if (enc_passwd) {
|
||||
encrypt_send_request_end();
|
||||
enc_passwd = 0;
|
||||
}
|
||||
}
|
||||
#endif /* ENCRYPTION */
|
||||
|
||||
/*
|
||||
* Do echo mode handling as soon as we know what the
|
||||
* linemode is going to be.
|
||||
* If the pty has echo turned off, then tell the client that
|
||||
* the server will echo. If echo is on, then the server
|
||||
* will echo if in character mode, but in linemode the
|
||||
* client should do local echoing. The state machine will
|
||||
* not send anything if it is unnecessary, so don't worry
|
||||
* about that here.
|
||||
*
|
||||
* If we need to send the WILL ECHO (because echo is off),
|
||||
* then delay that until after we have changed the MODE.
|
||||
* This way, when the user is turning off both editing
|
||||
* and echo, the client will get editing turned off first.
|
||||
* This keeps the client from going into encryption mode
|
||||
* and then right back out if it is doing auto-encryption
|
||||
* when passwords are being typed.
|
||||
*/
|
||||
if (uselinemode) {
|
||||
if (tty_isecho())
|
||||
send_wont(TELOPT_ECHO, 1);
|
||||
else
|
||||
need_will_echo = 1;
|
||||
#ifdef KLUDGELINEMODE
|
||||
if (lmodetype == KLUDGE_OK)
|
||||
lmodetype = KLUDGE_LINEMODE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* If linemode is being turned off, send appropriate
|
||||
* command and then we're all done.
|
||||
*/
|
||||
if (!uselinemode && linemode) {
|
||||
# ifdef KLUDGELINEMODE
|
||||
if (lmodetype == REAL_LINEMODE) {
|
||||
# endif /* KLUDGELINEMODE */
|
||||
send_dont(TELOPT_LINEMODE, 1);
|
||||
# ifdef KLUDGELINEMODE
|
||||
} else if (lmodetype == KLUDGE_LINEMODE)
|
||||
send_will(TELOPT_SGA, 1);
|
||||
# endif /* KLUDGELINEMODE */
|
||||
send_will(TELOPT_ECHO, 1);
|
||||
linemode = uselinemode;
|
||||
goto done;
|
||||
}
|
||||
|
||||
# ifdef KLUDGELINEMODE
|
||||
/*
|
||||
* If using real linemode check edit modes for possible later use.
|
||||
* If we are in kludge linemode, do the SGA negotiation.
|
||||
*/
|
||||
if (lmodetype == REAL_LINEMODE) {
|
||||
# endif /* KLUDGELINEMODE */
|
||||
useeditmode = 0;
|
||||
if (tty_isediting())
|
||||
useeditmode |= MODE_EDIT;
|
||||
if (tty_istrapsig())
|
||||
useeditmode |= MODE_TRAPSIG;
|
||||
if (tty_issofttab())
|
||||
useeditmode |= MODE_SOFT_TAB;
|
||||
if (tty_islitecho())
|
||||
useeditmode |= MODE_LIT_ECHO;
|
||||
# ifdef KLUDGELINEMODE
|
||||
} else if (lmodetype == KLUDGE_LINEMODE) {
|
||||
if (tty_isediting() && uselinemode)
|
||||
send_wont(TELOPT_SGA, 1);
|
||||
else
|
||||
send_will(TELOPT_SGA, 1);
|
||||
}
|
||||
# endif /* KLUDGELINEMODE */
|
||||
|
||||
/*
|
||||
* Negotiate linemode on if pty state has changed to turn it on.
|
||||
* Send appropriate command and send along edit mode, then all done.
|
||||
*/
|
||||
if (uselinemode && !linemode) {
|
||||
# ifdef KLUDGELINEMODE
|
||||
if (lmodetype == KLUDGE_LINEMODE) {
|
||||
send_wont(TELOPT_SGA, 1);
|
||||
} else if (lmodetype == REAL_LINEMODE) {
|
||||
# endif /* KLUDGELINEMODE */
|
||||
send_do(TELOPT_LINEMODE, 1);
|
||||
/* send along edit modes */
|
||||
(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB,
|
||||
TELOPT_LINEMODE, LM_MODE, useeditmode,
|
||||
IAC, SE);
|
||||
nfrontp += 7;
|
||||
editmode = useeditmode;
|
||||
# ifdef KLUDGELINEMODE
|
||||
}
|
||||
# endif /* KLUDGELINEMODE */
|
||||
linemode = uselinemode;
|
||||
goto done;
|
||||
}
|
||||
|
||||
# ifdef KLUDGELINEMODE
|
||||
/*
|
||||
* None of what follows is of any value if not using
|
||||
* real linemode.
|
||||
*/
|
||||
if (lmodetype < REAL_LINEMODE)
|
||||
goto done;
|
||||
# endif /* KLUDGELINEMODE */
|
||||
|
||||
if (linemode && his_state_is_will(TELOPT_LINEMODE)) {
|
||||
/*
|
||||
* If edit mode changed, send edit mode.
|
||||
*/
|
||||
if (useeditmode != editmode) {
|
||||
/*
|
||||
* Send along appropriate edit mode mask.
|
||||
*/
|
||||
(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB,
|
||||
TELOPT_LINEMODE, LM_MODE, useeditmode,
|
||||
IAC, SE);
|
||||
nfrontp += 7;
|
||||
editmode = useeditmode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for changes to special characters in use.
|
||||
*/
|
||||
start_slc(0);
|
||||
check_slc();
|
||||
(void) end_slc(0);
|
||||
}
|
||||
|
||||
done:
|
||||
if (need_will_echo)
|
||||
send_will(TELOPT_ECHO, 1);
|
||||
/*
|
||||
* Some things should be deferred until after the pty state has
|
||||
* been set by the local process. Do those things that have been
|
||||
* deferred now. This only happens once.
|
||||
*/
|
||||
if (_terminit == 0) {
|
||||
_terminit = 1;
|
||||
defer_terminit();
|
||||
}
|
||||
|
||||
netflush();
|
||||
set_termbuf();
|
||||
return;
|
||||
|
||||
} /* end of localstat */
|
||||
#endif /* LINEMODE */
|
||||
|
||||
/*
|
||||
* flowstat
|
||||
*
|
||||
* Check for changes to flow control
|
||||
*/
|
||||
void
|
||||
flowstat()
|
||||
{
|
||||
if (his_state_is_will(TELOPT_LFLOW)) {
|
||||
if (tty_flowmode() != flowmode) {
|
||||
flowmode = tty_flowmode();
|
||||
(void) sprintf(nfrontp, "%c%c%c%c%c%c",
|
||||
IAC, SB, TELOPT_LFLOW,
|
||||
flowmode ? LFLOW_ON : LFLOW_OFF,
|
||||
IAC, SE);
|
||||
nfrontp += 6;
|
||||
}
|
||||
if (tty_restartany() != restartany) {
|
||||
restartany = tty_restartany();
|
||||
(void) sprintf(nfrontp, "%c%c%c%c%c%c",
|
||||
IAC, SB, TELOPT_LFLOW,
|
||||
restartany ? LFLOW_RESTART_ANY
|
||||
: LFLOW_RESTART_XON,
|
||||
IAC, SE);
|
||||
nfrontp += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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(code, parm1, parm2)
|
||||
register int code, parm1, parm2;
|
||||
{
|
||||
void netflush();
|
||||
|
||||
/*
|
||||
* Get a copy of terminal characteristics.
|
||||
*/
|
||||
init_termbuf();
|
||||
|
||||
/*
|
||||
* Process request from client. code tells what it is.
|
||||
*/
|
||||
switch (code) {
|
||||
#ifdef LINEMODE
|
||||
case TELOPT_LINEMODE:
|
||||
/*
|
||||
* Don't do anything unless client is asking us to change
|
||||
* modes.
|
||||
*/
|
||||
uselinemode = (parm1 == WILL);
|
||||
if (uselinemode != linemode) {
|
||||
# ifdef KLUDGELINEMODE
|
||||
/*
|
||||
* If using kludge linemode, make sure that
|
||||
* we can do what the client asks.
|
||||
* We can not turn off linemode if alwayslinemode
|
||||
* and the ICANON bit is set.
|
||||
*/
|
||||
if (lmodetype == KLUDGE_LINEMODE) {
|
||||
if (alwayslinemode && tty_isediting()) {
|
||||
uselinemode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Quit now if we can't do it.
|
||||
*/
|
||||
if (uselinemode == linemode)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If using real linemode and linemode is being
|
||||
* turned on, send along the edit mode mask.
|
||||
*/
|
||||
if (lmodetype == REAL_LINEMODE && uselinemode)
|
||||
# else /* KLUDGELINEMODE */
|
||||
if (uselinemode)
|
||||
# endif /* KLUDGELINEMODE */
|
||||
{
|
||||
useeditmode = 0;
|
||||
if (tty_isediting())
|
||||
useeditmode |= MODE_EDIT;
|
||||
if (tty_istrapsig)
|
||||
useeditmode |= MODE_TRAPSIG;
|
||||
if (tty_issofttab())
|
||||
useeditmode |= MODE_SOFT_TAB;
|
||||
if (tty_islitecho())
|
||||
useeditmode |= MODE_LIT_ECHO;
|
||||
(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC,
|
||||
SB, TELOPT_LINEMODE, LM_MODE,
|
||||
useeditmode, IAC, SE);
|
||||
nfrontp += 7;
|
||||
editmode = useeditmode;
|
||||
}
|
||||
|
||||
|
||||
tty_setlinemode(uselinemode);
|
||||
|
||||
linemode = uselinemode;
|
||||
|
||||
if (!linemode)
|
||||
send_will(TELOPT_ECHO, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case LM_MODE:
|
||||
{
|
||||
register int ack, changed;
|
||||
|
||||
/*
|
||||
* Client has sent along a mode mask. If it agrees with
|
||||
* what we are currently doing, ignore it; if not, it could
|
||||
* be viewed as a request to change. Note that the server
|
||||
* will change to the modes in an ack if it is different from
|
||||
* what we currently have, but we will not ack the ack.
|
||||
*/
|
||||
useeditmode &= MODE_MASK;
|
||||
ack = (useeditmode & MODE_ACK);
|
||||
useeditmode &= ~MODE_ACK;
|
||||
|
||||
if (changed = (useeditmode ^ editmode)) {
|
||||
/*
|
||||
* This check is for a timing problem. If the
|
||||
* state of the tty has changed (due to the user
|
||||
* application) we need to process that info
|
||||
* before we write in the state contained in the
|
||||
* ack!!! This gets out the new MODE request,
|
||||
* and when the ack to that command comes back
|
||||
* we'll set it and be in the right mode.
|
||||
*/
|
||||
if (ack)
|
||||
localstat();
|
||||
if (changed & MODE_EDIT)
|
||||
tty_setedit(useeditmode & MODE_EDIT);
|
||||
|
||||
if (changed & MODE_TRAPSIG)
|
||||
tty_setsig(useeditmode & MODE_TRAPSIG);
|
||||
|
||||
if (changed & MODE_SOFT_TAB)
|
||||
tty_setsofttab(useeditmode & MODE_SOFT_TAB);
|
||||
|
||||
if (changed & MODE_LIT_ECHO)
|
||||
tty_setlitecho(useeditmode & MODE_LIT_ECHO);
|
||||
|
||||
set_termbuf();
|
||||
|
||||
if (!ack) {
|
||||
(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC,
|
||||
SB, TELOPT_LINEMODE, LM_MODE,
|
||||
useeditmode|MODE_ACK,
|
||||
IAC, SE);
|
||||
nfrontp += 7;
|
||||
}
|
||||
|
||||
editmode = useeditmode;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
} /* end of case LM_MODE */
|
||||
#endif /* LINEMODE */
|
||||
|
||||
case TELOPT_NAWS:
|
||||
#ifdef TIOCSWINSZ
|
||||
{
|
||||
struct winsize ws;
|
||||
|
||||
def_col = parm1;
|
||||
def_row = parm2;
|
||||
#ifdef LINEMODE
|
||||
/*
|
||||
* Defer changing window size until after terminal is
|
||||
* initialized.
|
||||
*/
|
||||
if (terminit() == 0)
|
||||
return;
|
||||
#endif /* LINEMODE */
|
||||
|
||||
/*
|
||||
* Change window size as requested by client.
|
||||
*/
|
||||
|
||||
ws.ws_col = parm1;
|
||||
ws.ws_row = parm2;
|
||||
(void) ioctl(pty, TIOCSWINSZ, (char *)&ws);
|
||||
}
|
||||
#endif /* TIOCSWINSZ */
|
||||
|
||||
break;
|
||||
|
||||
case TELOPT_TSPEED:
|
||||
{
|
||||
def_tspeed = parm1;
|
||||
def_rspeed = parm2;
|
||||
#ifdef LINEMODE
|
||||
/*
|
||||
* Defer changing the terminal speed.
|
||||
*/
|
||||
if (terminit() == 0)
|
||||
return;
|
||||
#endif /* LINEMODE */
|
||||
/*
|
||||
* Change terminal speed as requested by client.
|
||||
* We set the receive speed first, so that if we can't
|
||||
* store seperate 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 */
|
||||
|
||||
#if defined(CRAY2) && defined(UNICOS5)
|
||||
/*
|
||||
* Just in case of the likely event that we changed the pty state.
|
||||
*/
|
||||
rcv_ioctl();
|
||||
#endif /* defined(CRAY2) && defined(UNICOS5) */
|
||||
|
||||
netflush();
|
||||
|
||||
} /* end of clientstat */
|
||||
|
||||
#if defined(CRAY2) && defined(UNICOS5)
|
||||
void
|
||||
termstat()
|
||||
{
|
||||
needtermstat = 1;
|
||||
}
|
||||
|
||||
void
|
||||
_termstat()
|
||||
{
|
||||
needtermstat = 0;
|
||||
init_termbuf();
|
||||
localstat();
|
||||
rcv_ioctl();
|
||||
}
|
||||
#endif /* defined(CRAY2) && defined(UNICOS5) */
|
||||
|
||||
#ifdef LINEMODE
|
||||
/*
|
||||
* defer_terminit
|
||||
*
|
||||
* Some things should not be done until after the login process has started
|
||||
* and all the pty modes are set to what they are supposed to be. This
|
||||
* function is called when the pty state has been processed for the first time.
|
||||
* It calls other functions that do things that were deferred in each module.
|
||||
*/
|
||||
void
|
||||
defer_terminit()
|
||||
{
|
||||
|
||||
/*
|
||||
* local stuff that got deferred.
|
||||
*/
|
||||
if (def_tspeed != -1) {
|
||||
clientstat(TELOPT_TSPEED, def_tspeed, def_rspeed);
|
||||
def_tspeed = def_rspeed = 0;
|
||||
}
|
||||
|
||||
#ifdef TIOCSWINSZ
|
||||
if (def_col || def_row) {
|
||||
struct winsize ws;
|
||||
|
||||
memset((char *)&ws, 0, sizeof(ws));
|
||||
ws.ws_col = def_col;
|
||||
ws.ws_row = def_row;
|
||||
(void) ioctl(pty, TIOCSWINSZ, (char *)&ws);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The only other module that currently defers anything.
|
||||
*/
|
||||
deferslc();
|
||||
|
||||
} /* end of defer_terminit */
|
||||
|
||||
/*
|
||||
* terminit
|
||||
*
|
||||
* Returns true if the pty state has been processed yet.
|
||||
*/
|
||||
int
|
||||
terminit()
|
||||
{
|
||||
return(_terminit);
|
||||
|
||||
} /* end of terminit */
|
||||
#endif /* LINEMODE */
|
1192
contrib/telnet/telnetd/utility.c
Normal file
1192
contrib/telnet/telnetd/utility.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user