📄 utility.c
字号:
#ifdef ENCRYPTION nclearto = 0;#endif /* ENCRYPTION */ } DEBUG(debug_report, 1, debug_output_data ("td: netflush %d chars\r\n", n)); } /* end of netflush *//* * miscellaneous functions doing a variety of little jobs follow ... */voidfatal (int f, char *msg){ char buf[BUFSIZ]; snprintf (buf, sizeof buf, "telnetd: %s.\r\n", msg);#ifdef ENCRYPTION if (encrypt_output) { /* * Better turn off encryption first.... * Hope it flushes... */ encrypt_send_end (); netflush (); }#endif /* ENCRYPTION */ write (f, buf, (int)strlen (buf)); sleep (1); /*FIXME*/ exit (1);}voidfatalperror (int f, char *msg){ char buf[BUFSIZ]; snprintf (buf, sizeof buf, "%s: %s", msg, strerror (errno)); fatal (f, buf);}/* ************************************************************************* *//* Terminal determination */static unsigned char ttytype_sbbuf[] ={ IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE};static void_gettermname (){ if (his_state_is_wont (TELOPT_TTYPE)) return; settimer (baseline); net_output_datalen (ttytype_sbbuf, sizeof ttytype_sbbuf); ttloop (sequenceIs (ttypesubopt, baseline));}/* FIXME: should be getterminaltype (char *user_name, size_t size) Changes terminaltype. */intgetterminaltype (char *user_name){ int retval = -1; settimer (baseline);#if defined(AUTHENTICATION) /* * Handle the Authentication option before we do anything else. */ send_do (TELOPT_AUTHENTICATION, 1); ttloop (his_will_wont_is_changing (TELOPT_AUTHENTICATION)); if (his_state_is_will (TELOPT_AUTHENTICATION)) retval = auth_wait (user_name);#endif#ifdef ENCRYPTION send_will (TELOPT_ENCRYPT, 1);#endif /* ENCRYPTION */ send_do (TELOPT_TTYPE, 1); send_do (TELOPT_TSPEED, 1); send_do (TELOPT_XDISPLOC, 1); send_do (TELOPT_NEW_ENVIRON, 1); send_do (TELOPT_OLD_ENVIRON, 1);#ifdef ENCRYPTION ttloop (his_do_dont_is_changing (TELOPT_ENCRYPT) || his_will_wont_is_changing (TELOPT_TTYPE) || his_will_wont_is_changing (TELOPT_TSPEED) || his_will_wont_is_changing (TELOPT_XDISPLOC) || his_will_wont_is_changing (TELOPT_NEW_ENVIRON) || his_will_wont_is_changing (TELOPT_OLD_ENVIRON));#else ttloop (his_will_wont_is_changing (TELOPT_TTYPE) || his_will_wont_is_changing (TELOPT_TSPEED) || his_will_wont_is_changing (TELOPT_XDISPLOC) || his_will_wont_is_changing (TELOPT_NEW_ENVIRON) || his_will_wont_is_changing (TELOPT_OLD_ENVIRON));#endif #ifdef ENCRYPTION if (his_state_is_will (TELOPT_ENCRYPT)) encrypt_wait ();#endif if (his_state_is_will (TELOPT_TSPEED)) { static unsigned char sb[] = {IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE}; net_output_datalen (sb, sizeof sb); } if (his_state_is_will (TELOPT_XDISPLOC)) { static unsigned char sb[] = {IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE}; net_output_datalen (sb, sizeof sb); } if (his_state_is_will (TELOPT_NEW_ENVIRON)) { static unsigned char sb[] = {IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE}; net_output_datalen (sb, sizeof sb); } else if (his_state_is_will (TELOPT_OLD_ENVIRON)) { static unsigned char sb[] = {IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE}; net_output_datalen (sb, sizeof sb); } if (his_state_is_will (TELOPT_TTYPE)) net_output_datalen (ttytype_sbbuf, sizeof ttytype_sbbuf); if (his_state_is_will (TELOPT_TSPEED)) ttloop (sequenceIs (tspeedsubopt, baseline)); if (his_state_is_will (TELOPT_XDISPLOC)) ttloop (sequenceIs (xdisplocsubopt, baseline)); if (his_state_is_will (TELOPT_NEW_ENVIRON)) ttloop (sequenceIs (environsubopt, baseline)); if (his_state_is_will (TELOPT_OLD_ENVIRON)) ttloop (sequenceIs (oenvironsubopt, baseline)); if (his_state_is_will (TELOPT_TTYPE)) { char *first = NULL, *last = NULL; ttloop (sequenceIs (ttypesubopt, baseline)); /* * If the other side has already disabled the option, then * we have to just go with what we (might) have already gotten. */ if (his_state_is_will (TELOPT_TTYPE) && !terminaltypeok (terminaltype)) { if (first) free (first); first = xstrdup (terminaltype); for (;;) { /* Save the unknown name, and request the next name. */ if (last) free (last); last = xstrdup (terminaltype); _gettermname (); if (terminaltypeok (terminaltype)) break; if ((strcmp (last, terminaltype) == 0) || his_state_is_wont (TELOPT_TTYPE)) { /* * We've hit the end. If this is the same as * the first name, just go with it. */ if (strcmp (first, terminaltype) == 0) break; /* * Get the terminal name one more time, so that * RFC1091 compliant telnets will cycle back to * the start of the list. */ _gettermname (); if (strcmp (first, terminaltype) != 0) { free (terminaltype); terminaltype = xstrdup (first); } break; } } } if (first) free (first); if (last) free (last); } return retval;} intterminaltypeok (char *s){ char buf[1024]; if (terminaltype == NULL) return 1;#ifdef HAVE_LIBREADLINE if (tgetent (buf, s) == 0)#endif return 0; return 1;}/* ************************************************************************* *//* Debugging support */static FILE *debug_fp = NULL;static intdebug_open (){ int um = umask(077); if (!debug_fp) debug_fp = fopen ("/tmp/telnet.debug", "a"); umask(um); return debug_fp == NULL;}static intdebug_close (){ if (debug_fp) fclose (debug_fp); debug_fp = NULL;}voiddebug_output_datalen (const char *data, size_t len){ if (debug_open ()) return; fwrite (data, 1, len, debug_fp); debug_close ();}voiddebug_output_data (const char *fmt, ...){ va_list ap; if (debug_open ()) return; va_start (ap, fmt); vfprintf (debug_fp, fmt, ap); va_end (ap); debug_close ();}/* * Print telnet options and commands in plain text, if possible. */voidprintoption(register char *fmt, register int option){ if (TELOPT_OK(option)) debug_output_data ("%s %s\r\n", fmt, TELOPT(option)); else if (TELCMD_OK(option)) debug_output_data ("%s %s\r\n", fmt, TELCMD(option)); else debug_output_data ("%s %d\r\n", fmt, option);}/* char direction; '<' or '>' *//* unsigned char *pointer; where suboption data sits *//* int length; length of suboption data */voidprintsub(int direction, unsigned char *pointer, int length){ register int i; char buf[512]; if (direction) { debug_output_data ("td: %s suboption ", direction == '<' ? "recv" : "send"); if (length >= 3) { register int j; i = pointer[length-2]; j = pointer[length-1]; if (i != IAC || j != SE) { debug_output_data ("(terminated by "); if (TELOPT_OK(i)) debug_output_data ("%s ", TELOPT(i)); else if (TELCMD_OK(i)) debug_output_data ("%s ", TELCMD(i)); else debug_output_data ("%d ", i); if (TELOPT_OK(j)) debug_output_data ("%s", TELOPT(j)); else if (TELCMD_OK(j)) debug_output_data ("%s", TELCMD(j)); else debug_output_data ("%d", j); debug_output_data (", not IAC SE!) "); } } length -= 2; } if (length < 1) { debug_output_data ("(Empty suboption??\?)"); return; } switch (pointer[0]) { case TELOPT_TTYPE: debug_output_data ("TERMINAL-TYPE "); switch (pointer[1]) { case TELQUAL_IS: debug_output_data ("IS \"%.*s\"", length-2, (char *)pointer+2); break; case TELQUAL_SEND: debug_output_data ("SEND"); break; default: debug_output_data ("- unknown qualifier %d (0x%x).", pointer[1], pointer[1]); } break; case TELOPT_TSPEED: debug_output_data ("TERMINAL-SPEED"); if (length < 2) { debug_output_data (" (empty suboption??\?)"); break; } switch (pointer[1]) { case TELQUAL_IS: debug_output_data (" IS %.*s", length-2, (char *)pointer+2); break; default: if (pointer[1] == 1) debug_output_data (" SEND"); else debug_output_data (" %d (unknown)", pointer[1]); for (i = 2; i < length; i++) { debug_output_data (" ?%d?", pointer[i]); } break; } break; case TELOPT_LFLOW: debug_output_data ("TOGGLE-FLOW-CONTROL"); if (length < 2) { debug_output_data (" (empty suboption??\?)"); break; } switch (pointer[1]) { case LFLOW_OFF: debug_output_data (" OFF"); break; case LFLOW_ON: debug_output_data (" ON"); break; case LFLOW_RESTART_ANY: debug_output_data (" RESTART-ANY"); break; case LFLOW_RESTART_XON: debug_output_data (" RESTART-XON"); break; default: debug_output_data (" %d (unknown)", pointer[1]); } for (i = 2; i < length; i++) debug_output_data (" ?%d?", pointer[i]); break; case TELOPT_NAWS: debug_output_data ("NAWS"); if (length < 2) { debug_output_data (" (empty suboption??\?)"); break; } if (length == 2) { debug_output_data (" ?%d?", pointer[1]); break; } debug_output_data (" %d %d (%d)", pointer[1], pointer[2], (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); if (length == 4) { debug_output_data (" ?%d?", pointer[3]); break; } debug_output_data (" %d %d (%d)", pointer[3], pointer[4], (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); for (i = 5; i < length; i++) debug_output_data (" ?%d?", pointer[i]); break; case TELOPT_LINEMODE: debug_output_data ("LINEMODE "); if (length < 2) { debug_output_data (" (empty suboption??\?)"); break; } switch (pointer[1]) { case WILL: debug_output_data ("WILL "); goto common; case WONT: debug_output_data ("WONT "); goto common; case DO: debug_output_data ("DO "); goto common; case DONT: debug_output_data ("DONT "); common: if (length < 3) { debug_output_data ("(no option??\?)"); break; } switch (pointer[2]) { case LM_FORWARDMASK: debug_output_data ("Forward Mask"); for (i = 3; i < length; i++) debug_output_data (" %x", pointer[i]); break; default: debug_output_data ("%d (unknown)", pointer[2]); for (i = 3; i < length; i++) debug_output_data (" %d", pointer[i]); break; } break; case LM_SLC: debug_output_data ("SLC"); for (i = 2; i < length - 2; i += 3) { if (SLC_NAME_OK(pointer[i+SLC_FUNC])) debug_output_data (" %s", SLC_NAME(pointer[i+SLC_FUNC])); else debug_output_data (" %d", pointer[i+SLC_FUNC]); switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { case SLC_NOSUPPORT: debug_output_data (" NOSUPPORT"); break; case SLC_CANTCHANGE: debug_output_data (" CANTCHANGE"); break; case SLC_VARIABLE: debug_output_data (" VARIABLE"); break; case SLC_DEFAULT: debug_output_data (" DEFAULT"); break; } debug_output_data ("%s%s%s", pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| SLC_FLUSHOUT| SLC_LEVELBITS)) debug_output_data ("(0x%x)", pointer[i+SLC_FLAGS]); debug_output_data (" %d;", pointer[i+SLC_VALUE]); if ((pointer[i+SLC_VALUE] == IAC) && (pointer[i+SLC_VALUE+1] == IAC)) i++; } for (; i < length; i++) debug_output_data (" ?%d?", pointer[i]); break; case LM_MODE: debug_output_data ("MODE "); if (length < 3) { debug_output_data ("(no mode??\?)"); break; } { char tbuf[32]; snprintf(tbuf, sizeof(tbuf), "%s%s%s%s%s", pointer[2]&MODE_EDIT ? "|EDIT" : "", pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", pointer[2]&MODE_ACK ? "|ACK" : ""); debug_output_data ("%s", tbuf[1] ? &tbuf[1] : "0"); } if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) debug_output_data (" (0x%x)", pointer[2]); for (i = 3; i < length; i++) debug_output_data (" ?0x%x?", pointer[i]); break; default: debug_output_data ("%d (unknown)", pointer[1]); for (i = 2; i < length; i++) debug_output_data (" %d", pointer[i]); } break; case TELOPT_STATUS: { register char *cp; register int j, k; debug_output_data ("STATUS"); switch (pointer[1]) { default: if (pointer[1] == TELQUAL_SEND) debug_output_data (" SEND"); else debug_output_data (" %d (unknown)", pointer[1]); for (i = 2; i < length; i++) debug_output_data (" ?%d?", pointer[i]); break; case TELQUAL_IS: debug_output_data (" IS\r\n"); for (i = 2; i < length; i++) { switch(pointer[i]) { case DO: cp = "DO"; goto common2; case DONT: cp = "DONT"; goto common2; case WILL: cp = "WILL"; goto common2; case WONT: cp = "WONT"; goto common2; common2: i++; if (TELOPT_OK(pointer[i])) debug_output_data (" %s %s\r\n", cp, TELOPT(pointer[i])); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -