📄 ckctel.c
字号:
char *cktelv = "Telnet support, 8.0.269, 4 Mar 2004";#define CKCTEL_Cint sstelnet = 0; /* Do server-side Telnet negotiation *//* C K C T E L -- Telnet support *//* Authors: Telnet protocol by Frank da Cruz and Jeffrey Altman. Telnet Forward X by Jeffrey Altman Telnet START_TLS support by Jeffrey Altman Telnet AUTH and ENCRYPT support by Jeffrey Altman Telnet COMPORT support by Jeffrey Altman Telnet NEW-ENVIRONMENT support by Jeffrey Altman Telnet NAWS support by Frank da Cruz and Jeffrey Altman Telnet TERMTYPE support by Jeffrey Altman Telnet KERMIT support by Jeffrey Altman Other contributions as indicated in the code. Copyright (C) 1985, 2004, Trustees of Columbia University in the City of New York. All rights reserved. See the C-Kermit COPYING.TXT file or the copyright text in the ckcmai.c module for disclaimer and permissions.*//* NOTE TO CONTRIBUTORS: This file, and all the other shared (ckc and cku) C-Kermit source files, must be compatible with C preprocessors that support only #ifdef, #else, #endif, #define, and #undef. Please do not use #if, logical operators, or other preprocessor features in this module. Also, don't use any ANSI C constructs except within #ifdef CK_ANSIC..#endif.*/#include "ckcsym.h"#include "ckcdeb.h"#ifdef TNCODE#include "ckcker.h"#define TELCMDS /* to define name array */#define TELOPTS /* to define name array */#define SLC_NAMES /* to define name array */#define ENCRYPT_NAMES#define AUTH_NAMES#define TELOPT_STATES#define TELOPT_MODES#define TNC_NAMES#include "ckcnet.h"#include "ckctel.h"#ifdef CK_AUTHENTICATION#include "ckuath.h"#endif /* CK_AUTHENTICATION */#ifdef CK_SSL#include "ck_ssl.h"#endif /* CK_SSL */#ifndef NOTERM#ifdef OS2 /* For terminal type name string */#include "ckuusr.h"#ifndef NT#include <os2.h>#undef COMMENT#else#define isascii __isascii#endif /* NT */#include "ckocon.h"extern int tt_type, max_tt;extern struct tt_info_rec tt_info[];#endif /* OS2 */#endif /* NOTERM */#ifdef OS2#include <assert.h>#ifdef NT#include <setjmpex.h>#else /* NT */#include <setjmp.h>#endif /* NT */#include <signal.h>#include "ckcsig.h"#include "ckosyn.h"#endif /* OS2 */#ifdef CK_NAWS /* Negotiate About Window Size */#ifdef RLOGCODE_PROTOTYP( int rlog_naws, (void) );#endif /* RLOGCODE */#endif /* CK_NAWS */int tn_init = 0; /* Telnet protocol initialized flag */int tn_begun = 0; /* Telnet protocol started flag */static int tn_first = 1; /* First time init flag */extern int tn_exit; /* Exit on disconnect */extern int inserver; /* Running as IKSD */char *tn_term = NULL; /* Terminal type override */#ifdef CK_SNDLOCchar *tn_loc = NULL; /* Location override */#endif /* CK_SNDLOC */int tn_nlm = TNL_CRLF; /* Telnet CR -> CR LF mode */int tn_b_nlm = TNL_CR; /* Telnet Binary CR RAW mode */int tn_b_meu = 0; /* Telnet Binary ME means U too */int tn_b_ume = 0; /* Telnet Binary U means ME too */int tn_wait_flg = 1; /* Telnet Wait for Negotiations */int tn_infinite = 0; /* Telnet Bug Infinite-Loop-Check */int tn_rem_echo = 1; /* We will echo if WILL ECHO */int tn_b_xfer = 0; /* Telnet Binary for Xfers? */int tn_sb_bug = 1; /* Telnet BUG - SB w/o WILL or DO */int tn_auth_krb5_des_bug = 1; /* Telnet BUG - AUTH KRB5 DES */ /* truncates long keys */int tn_no_encrypt_xfer = 0; /* Turn off Telnet Encrypt? */int tn_delay_sb = 1; /* Delay SBs until safe */int tn_auth_how = TN_AUTH_HOW_ANY;int tn_auth_enc = TN_AUTH_ENC_ANY;int tn_deb = 0; /* Telnet Debug mode */int tn_sfu = 0; /* Microsoft SFU compatibility */#ifdef CK_FORWARD_Xchar * tn_fwdx_xauthority = NULL; /* Xauthority File */int fwdx_no_encrypt = 0; /* Forward-X requires encryption */#endif /* CK_FORWARD_X */#ifdef OS2int ttnum = -1; /* Last Telnet Terminal Type sent */int ttnumend = 0; /* Has end of list been found */#endif /* OS2 */char tn_msg[TN_MSG_LEN]; /* Telnet data can be rather long */char hexbuf[TN_MSG_LEN];char tn_msg_out[TN_MSG_LEN];#ifdef CK_FORWARD_XCHAR fwdx_msg_out[TN_MSG_LEN];#endif /* CK_FORWARD_X *//* In order to prevent an infinite telnet negotiation loop we maintain a count of the number of times the same telnet negotiation message is sent. When this count hits MAXTNCNT, we do not send any more of the message. The count is stored in the tncnts[][] array. The tncnts[][] array is indexed by negotiation option (SUPPRESS GO AHEAD, TERMINAL TYPE, NAWS, etc. - see the tnopts[] array) and the four negotiation message types (WILL, WONT, DO, DONT). All telnet negotiations are kept track of in this way. The count for a message is zeroed when the "opposite" message is sent. WILL is the opposite of WONT, and DO is the opposite of DONT. For example sending "WILL SGA" increments tncnts[TELOPT_SGA][0] and zeroes tncnts[TELOPT_SGA][1]. The code that does this is in tn_sopt(). rogersh@fsj.co.jp, 18/3/1995 8/16/1998 - with the recent rewrite of the telnet state machine I don't think this code is necessary anymore. However, it can't do any harm so I am leaving it in. - Jeff 12/28/1998 - all references to tncnts[] must be done with TELOPT_INDEX(opt) because the Telnet option list is no longer contiguous. We also must allocate NTELOPTS + 1 because the TELOPT_INDEX() macro returns NTELOPTS for an invalid option number.*/#define MAXTNCNT 4 /* Permits 4 intermediate telnet firewalls/gateways */char tncnts[NTELOPTS+1][4]; /* Counts */char tnopps[4] = { 1,0,3,2 }; /* Opposites */#ifdef CK_ENVIRONMENT#ifdef CK_FORWARD_X#define TSBUFSIZ 2056#else /* CK_FORWARD_X */#define TSBUFSIZ 1024#endif /* CK_FORWARD_X */char tn_env_acct[64];char tn_env_disp[64];char tn_env_job[64];char tn_env_prnt[64];char tn_env_sys[64];char * tn_env_uservar[8][2];int tn_env_flg = 1;#else /* CK_ENVIRONMENT */#define TSBUFSIZ 41int tn_env_flg = 0;#endif /* CK_ENVIRONMENT */#ifdef COMMENT/* SIGWINCH handler moved to ckuusx.c */#ifndef NOSIGWINCH#ifdef CK_NAWS /* Window size business */#ifdef UNIX#include <signal.h>#endif /* UNIX */#endif /* CK_NAWS */#endif /* NOSIGWINCH */#endif /* COMMENT */CHAR sb[TSBUFSIZ]; /* Buffer - incoming subnegotiations */CHAR sb_out[TSBUFSIZ]; /* Buffer - outgoing subnegotiations */int tn_duplex = 1; /* Local echo */extern char uidbuf[]; /* User ID buffer */extern int quiet, ttnet, ttnproto, debses, what, duplex, oldplex, local;extern int seslog, sessft, whyclosed;#ifdef OS2#ifndef NOTERMextern int tt_rows[], tt_cols[];extern int tt_status[VNUM];extern int scrninitialized[];#endif /* NOTERM */#else /* OS2 */extern int tt_rows, tt_cols; /* Everybody has this */#endif /* OS2 */extern int cmd_cols, cmd_rows;extern char namecopy[];extern char myipaddr[]; /* Global copy of my IP address */#ifndef TELOPT_MACROinttelopt_index(opt) int opt; { if (opt >= 0 && opt <= TELOPT_STDERR) return(opt); else if (opt >= TELOPT_PRAGMA_LOGON && opt <= TELOPT_PRAGMA_HEARTBEAT) return(opt-88); else if (opt == TELOPT_IBM_SAK) return(opt-147); else return(NTELOPTS);}inttelopt_ok(opt) int opt; { return((opt >= TELOPT_BINARY && opt <= TELOPT_STDERR) || (opt >= TELOPT_PRAGMA_LOGON && opt <= TELOPT_PRAGMA_HEARTBEAT) || (opt == TELOPT_IBM_SAK));}CHAR *telopt(opt) int opt; { if (telopt_ok(opt)) return((CHAR *)telopts[telopt_index(opt)]); else return((CHAR *)"UNKNOWN");}inttelopt_mode_ok(opt) int opt; { return((unsigned int)(opt) <= TN_NG_MU);}CHAR *telopt_mode(opt) int opt; { if (telopt_mode_ok(opt)) return((CHAR *)telopt_modes[opt-TN_NG_RF]); else return((CHAR *)"UNKNOWN");}#endif /* TELOPT_MACRO */static inttn_outst(notquiet) int notquiet; { int outstanding = 0; int x = 0;#ifdef CK_ENCRYPTION int e = 0; int d = 0;#endif /* CK_ENCRYPTION */ if (tn_wait_flg) { for (x = TELOPT_FIRST; x <= TELOPT_LAST; x++) { if (TELOPT_OK(x)) { if (TELOPT_UNANSWERED_WILL(x)) { if ( notquiet ) printf("?Telnet waiting for response to WILL %s\r\n", TELOPT(x)); debug(F111,"tn_outst","unanswered WILL",x); outstanding = 1; if ( !notquiet ) break; } if (TELOPT_UNANSWERED_DO(x)) { if ( notquiet ) printf("?Telnet waiting for response to DO %s\r\n", TELOPT(x)); debug(F111,"tn_outst","unanswered DO",x); outstanding = 1; if ( !notquiet ) break; } if (TELOPT_UNANSWERED_WONT(x)) { if ( notquiet ) printf("?Telnet waiting for response to WONT %s\r\n", TELOPT(x)); debug(F111,"tn_outst","unanswered WONT",x); outstanding = 1; if ( !notquiet ) break; } if (TELOPT_UNANSWERED_DONT(x)) { if ( notquiet ) printf("?Telnet waiting for response to DONT %s\r\n", TELOPT(x)); debug(F111,"tn_outst","unanswered DONT",x); outstanding = 1; if ( !notquiet ) break; } if (TELOPT_UNANSWERED_SB(x)) { if ( notquiet ) printf("?Telnet waiting for response to SB %s\r\n", TELOPT(x)); debug(F111,"tn_outst","unanswered SB",x); outstanding = 1; if ( !notquiet ) break; } } }#ifdef CK_AUTHENTICATION if (ck_tn_auth_in_progress()) { if (TELOPT_ME(TELOPT_AUTHENTICATION)) { if (notquiet) printf("?Telnet waiting for WILL %s subnegotiation\r\n", TELOPT(TELOPT_AUTHENTICATION)); debug(F111, "tn_outst", "ME authentication in progress", TELOPT_AUTHENTICATION ); outstanding = 1; } else if (TELOPT_U(TELOPT_AUTHENTICATION)) { if (notquiet) printf("?Telnet waiting for DO %s subnegotiation\r\n", TELOPT(TELOPT_AUTHENTICATION)); debug(F111, "tn_outst", "U authentication in progress", TELOPT_AUTHENTICATION ); outstanding = 1; } }#endif /* CK_AUTHENTICATION */#ifdef CK_ENCRYPTION if (!outstanding) { e = ck_tn_encrypting(); d = ck_tn_decrypting(); if (TELOPT_ME(TELOPT_ENCRYPTION)) { if (TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop && e || !TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop && !e ) { if ( notquiet ) printf("?Telnet waiting for WILL %s subnegotiation\r\n", TELOPT(TELOPT_ENCRYPTION)); debug(F111, "tn_outst", "encryption mode switch", TELOPT_ENCRYPTION ); outstanding = 1; } } if (TELOPT_U(TELOPT_ENCRYPTION)) { if (TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop && d || !TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop && !d ) { if ( notquiet ) printf("?Telnet waiting for DO %s subnegotiation\r\n", TELOPT(TELOPT_ENCRYPTION)); debug(F111, "tn_outst", "decryption mode switch", TELOPT_ENCRYPTION ); outstanding = 1; } } }#endif /* CK_ENCRYPTION */ } /* if (tn_wait_flg) */#ifdef IKS_OPTION /* Even if we are not waiting for Telnet options we must wait for */ /* Kermit Telnet Subnegotiations if we have sent a request to the */ /* other guy. Otherwise we will get out of sync. */ if (!outstanding) { if (TELOPT_U(TELOPT_KERMIT) && (TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start || TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop || !TELOPT_SB(TELOPT_KERMIT).kermit.sop) ) { if ( notquiet ) printf("?Telnet waiting for SB %s negotiation\r\n", TELOPT(TELOPT_KERMIT)); debug(F111,"tn_outst","U kermit in progress",TELOPT_KERMIT); outstanding = 1; } }#endif /* IKS_OPTION */#ifdef TN_COMPORT if (!outstanding) { if (TELOPT_ME(TELOPT_COMPORT)) { if (TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb) { if (notquiet) printf("?Telnet waiting for SB %s negotiation\r\n", TELOPT(TELOPT_COMPORT)); debug(F111,"tn_outst","ComPort SB in progress",TELOPT_COMPORT); outstanding = 1; } if (TELOPT_SB(TELOPT_COMPORT).comport.wait_for_ms) { if (notquiet)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -