diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 1998-03-12 04:57:48 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 1998-03-12 04:57:48 +0000 |
commit | ff07d4940bd49261ee22ce0ace862e5589593044 (patch) | |
tree | f425ce5c7200ee7aba8c8aef0e45753733167523 /usr.bin/telnet/telnet.c | |
parent | dc9f07b18d9385c5d9662784d3fd1ac69b5c271a (diff) |
encryption support from kth-krb 0.9.8 (kerberos only)
plus some tweaks for better binary/8-bit support.
Diffstat (limited to 'usr.bin/telnet/telnet.c')
-rw-r--r-- | usr.bin/telnet/telnet.c | 249 |
1 files changed, 125 insertions, 124 deletions
diff --git a/usr.bin/telnet/telnet.c b/usr.bin/telnet/telnet.c index a66cc315846..4da88cb6d39 100644 --- a/usr.bin/telnet/telnet.c +++ b/usr.bin/telnet/telnet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: telnet.c,v 1.3 1997/06/05 01:07:39 deraadt Exp $ */ +/* $OpenBSD: telnet.c,v 1.4 1998/03/12 04:57:43 art Exp $ */ /* $NetBSD: telnet.c,v 1.7 1996/02/28 21:04:15 thorpej Exp $ */ /* @@ -34,38 +34,9 @@ * SUCH DAMAGE. */ -#ifndef lint -#if 0 -static char sccsid[] = "@(#)telnet.c 8.4 (Berkeley) 5/30/95"; -static char rcsid[] = "$NetBSD: telnet.c,v 1.7 1996/02/28 21:04:15 thorpej Exp $"; -#else -static char rcsid[] = "$OpenBSD: telnet.c,v 1.3 1997/06/05 01:07:39 deraadt Exp $"; -#endif -#endif /* not lint */ - -#include <sys/types.h> - -#if defined(unix) -#include <signal.h> -/* By the way, we need to include curses.h before telnet.h since, - * among other things, telnet.h #defines 'DO', which is a variable - * declared in curses.h. - */ -#endif /* defined(unix) */ - -#include <arpa/telnet.h> - -#include <ctype.h> - -#include "ring.h" +#include "telnet_locl.h" -#include "defines.h" -#include "externs.h" -#include "types.h" -#include "general.h" - - -#define strip(x) ((my_want_state_is_wont(TELOPT_BINARY)) ? ((x)&0x7f) : (x)) +#define strip(x) (eight ? (x) : ((x) & 0x7f)) static unsigned char subbuffer[SUBBUFSIZE], *subpointer, *subend; /* buffer for sub-options */ @@ -85,7 +56,8 @@ char do_dont_resp[256]; char will_wont_resp[256]; int - eight = 0, + eight = 3, + binary = 0, autologin = 0, /* Autologin anyone? */ skiprc = 0, connected, @@ -159,18 +131,6 @@ int kludgelinemode = 1; */ Clocks clocks; - -#ifdef notdef -Modelist modelist[] = { - { "telnet command mode", COMMAND_LINE }, - { "character-at-a-time mode", 0 }, - { "character-at-a-time mode (local echo)", LOCAL_ECHO|LOCAL_CHARS }, - { "line-by-line mode (remote echo)", LINE | LOCAL_CHARS }, - { "line-by-line mode", LINE | LOCAL_ECHO | LOCAL_CHARS }, - { "line-by-line mode (local echoing suppressed)", LINE | LOCAL_CHARS }, - { "3270 mode", 0 }, -}; -#endif /* @@ -183,12 +143,12 @@ init_telnet() env_init(); SB_CLEAR(); - ClearArray(options); + memset((char *)options, 0, sizeof options); connected = In3270 = ISend = localflow = donebinarytoggle = 0; -#if defined(AUTHENTICATION) +#if defined(AUTHENTICATION) || defined(ENCRYPTION) auth_encrypt_connect(connected); -#endif /* defined(AUTHENTICATION) */ +#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ restartany = -1; SYNCHing = 0; @@ -206,56 +166,6 @@ init_telnet() } -#ifdef notdef -#include <varargs.h> - - /*VARARGS*/ - static void -printring(va_alist) - va_dcl -{ - va_list ap; - char buffer[100]; /* where things go */ - char *ptr; - char *format; - char *string; - Ring *ring; - int i; - - va_start(ap); - - ring = va_arg(ap, Ring *); - format = va_arg(ap, char *); - ptr = buffer; - - while ((i = *format++) != 0) { - if (i == '%') { - i = *format++; - switch (i) { - case 'c': - *ptr++ = va_arg(ap, int); - break; - case 's': - string = va_arg(ap, char *); - ring_supply_data(ring, buffer, ptr-buffer); - ring_supply_data(ring, string, strlen(string)); - ptr = buffer; - break; - case 0: - ExitString("printring: trailing %%.\n", 1); - /*NOTREACHED*/ - default: - ExitString("printring: unknown format character.\n", 1); - /*NOTREACHED*/ - } - } else { - *ptr++ = i; - } - } - ring_supply_data(ring, buffer, ptr-buffer); -} -#endif - /* * These routines are in charge of sending option negotiations * to the other side. @@ -378,6 +288,9 @@ willoption(option) #if defined(AUTHENTICATION) case TELOPT_AUTHENTICATION: #endif +#if defined(ENCRYPTION) + case TELOPT_ENCRYPT: +#endif new_state_ok = 1; break; @@ -407,6 +320,11 @@ willoption(option) } } set_my_state_do(option); +#if defined(ENCRYPTION) + if (option == TELOPT_ENCRYPT) + encrypt_send_support(); +#endif + } void @@ -440,6 +358,11 @@ wontoption(option) set_my_state_dont(option); return; /* Never reply to TM will's/wont's */ +#ifdef ENCRYPTION + case TELOPT_ENCRYPT: + encrypt_not(); + break; +#endif default: break; } @@ -494,6 +417,9 @@ dooption(option) case TELOPT_LFLOW: /* local flow control */ case TELOPT_TTYPE: /* terminal type option */ case TELOPT_SGA: /* no big deal */ +#if defined(ENCRYPTION) + case TELOPT_ENCRYPT: /* encryption variable option */ +#endif new_state_ok = 1; break; @@ -683,7 +609,8 @@ mklist(buf, name) * Skip entries with spaces or non-ascii values. * Convert lower case letters to upper case. */ - if ((c == ' ') || !isascii(c)) +#define ISASCII(c) (!((c)&0x80)) + if ((c == ' ') || !ISASCII(c)) n = 1; else if (islower(c)) *cp = toupper(c); @@ -739,12 +666,11 @@ is_unique(name, as, ae) return (1); } -#ifdef TERMCAP -char termbuf[1024]; +static char termbuf[1024]; /*ARGSUSED*/ int -setupterm(tname, fd, errp) +telnet_setupterm(tname, fd, errp) char *tname; int fd, *errp; { @@ -758,10 +684,6 @@ setupterm(tname, fd, errp) *errp = 0; return(-1); } -#else -#define termbuf ttytype -extern char ttytype[]; -#endif int resettermname = 1; @@ -778,7 +700,7 @@ gettermname() if (tnamep && tnamep != unknown) free(tnamep); if ((tname = (char *)env_getvalue((unsigned char *)"TERM")) && - (setupterm(tname, 1, &err) == 0)) { + (telnet_setupterm(tname, 1, &err) == 0)) { tnamep = mklist(termbuf, tname); } else { if (tname && ((int)strlen(tname) <= 40)) { @@ -833,8 +755,9 @@ suboption() name = gettermname(); len = strlen(name) + 4 + 2; if (len < NETROOM()) { - sprintf((char *)temp, "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE, - TELQUAL_IS, name, IAC, SE); + snprintf((char *)temp, sizeof(temp), + "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE, + TELQUAL_IS, name, IAC, SE); ring_supply_data(&netoring, temp, len); printsub('>', &temp[2], len-2); } else { @@ -855,8 +778,9 @@ suboption() TerminalSpeeds(&ispeed, &ospeed); - sprintf((char *)temp, "%c%c%c%c%d,%d%c%c", IAC, SB, TELOPT_TSPEED, - TELQUAL_IS, ospeed, ispeed, IAC, SE); + snprintf((char *)temp, sizeof(temp), + "%c%c%c%c%d,%d%c%c", IAC, SB, TELOPT_TSPEED, + TELQUAL_IS, ospeed, ispeed, IAC, SE); len = strlen((char *)temp+4) + 4; /* temp[3] is 0 ... */ if (len < NETROOM()) { @@ -960,7 +884,8 @@ suboption() send_wont(TELOPT_XDISPLOC, 1); break; } - sprintf((char *)temp, "%c%c%c%c%s%c%c", IAC, SB, TELOPT_XDISPLOC, + snprintf((char *)temp, sizeof(temp), + "%c%c%c%c%s%c%c", IAC, SB, TELOPT_XDISPLOC, TELQUAL_IS, dp, IAC, SE); len = strlen((char *)temp+4) + 4; /* temp[3] is 0 ... */ @@ -1003,6 +928,67 @@ suboption() } break; #endif +#if defined(ENCRYPTION) + case TELOPT_ENCRYPT: + if (SB_EOF()) + return; + switch(SB_GET()) { + case ENCRYPT_START: + if (my_want_state_is_dont(TELOPT_ENCRYPT)) + return; + encrypt_start(subpointer, SB_LEN()); + break; + case ENCRYPT_END: + if (my_want_state_is_dont(TELOPT_ENCRYPT)) + return; + encrypt_end(); + break; + case ENCRYPT_SUPPORT: + if (my_want_state_is_wont(TELOPT_ENCRYPT)) + return; + encrypt_support(subpointer, SB_LEN()); + break; + case ENCRYPT_REQSTART: + if (my_want_state_is_wont(TELOPT_ENCRYPT)) + return; + encrypt_request_start(subpointer, SB_LEN()); + break; + case ENCRYPT_REQEND: + if (my_want_state_is_wont(TELOPT_ENCRYPT)) + return; + /* + * We can always send an REQEND so that we cannot + * get stuck encrypting. We should only get this + * if we have been able to get in the correct mode + * anyhow. + */ + encrypt_request_end(); + break; + case ENCRYPT_IS: + if (my_want_state_is_dont(TELOPT_ENCRYPT)) + return; + encrypt_is(subpointer, SB_LEN()); + break; + case ENCRYPT_REPLY: + if (my_want_state_is_wont(TELOPT_ENCRYPT)) + return; + encrypt_reply(subpointer, SB_LEN()); + break; + case ENCRYPT_ENC_KEYID: + if (my_want_state_is_dont(TELOPT_ENCRYPT)) + return; + encrypt_enc_keyid(subpointer, SB_LEN()); + break; + case ENCRYPT_DEC_KEYID: + if (my_want_state_is_wont(TELOPT_ENCRYPT)) + return; + encrypt_dec_keyid(subpointer, SB_LEN()); + break; + default: + break; + } + break; +#endif default: break; } @@ -1150,7 +1136,7 @@ slc_init() #define initfunc(func, flags) { \ spcp = &spc_data[func]; \ - if (spcp->valp = tcval(func)) { \ + if ((spcp->valp = tcval(func))) { \ spcp->val = *spcp->valp; \ spcp->mylevel = SLC_VARIABLE|flags; \ } else { \ @@ -1558,12 +1544,12 @@ env_opt_add(ep) if (ep == NULL || *ep == '\0') { /* Send user defined variables first. */ env_default(1, 0); - while (ep = env_default(0, 0)) + while ((ep = env_default(0, 0))) env_opt_add(ep); /* Now add the list of well know variables. */ env_default(1, 1); - while (ep = env_default(0, 1)) + while ((ep = env_default(0, 1))) env_opt_add(ep); return; } @@ -1583,7 +1569,7 @@ env_opt_add(ep) opt_replyp = opt_reply + len - (opt_replyend - opt_replyp); opt_replyend = opt_reply + len; } - if (opt_welldefined(ep)) + if (opt_welldefined((char *)ep)) #ifdef OLD_ENVIRON if (telopt_environ == TELOPT_OLD_ENVIRON) *opt_replyp++ = old_env_var; @@ -1593,7 +1579,7 @@ env_opt_add(ep) else *opt_replyp++ = ENV_USERVAR; for (;;) { - while (c = *ep++) { + while ((c = *ep++)) { switch(c&0xff) { case IAC: *opt_replyp++ = IAC; @@ -1607,7 +1593,7 @@ env_opt_add(ep) } *opt_replyp++ = c; } - if (ep = vp) { + if ((ep = vp)) { #ifdef OLD_ENVIRON if (telopt_environ == TELOPT_OLD_ENVIRON) *opt_replyp++ = old_env_value; @@ -1684,6 +1670,10 @@ telrcv() } c = *sbp++ & 0xff, scc--; count++; +#if defined(ENCRYPTION) + if (decrypt_input) + c = (*decrypt_input)(c); +#endif switch (telrcv_state) { @@ -1718,7 +1708,7 @@ telrcv() # endif /* defined(TN3270) */ /* * The 'crmod' hack (see following) is needed - * since we can't * set CRMOD on output only. + * since we can't set CRMOD on output only. * Machines like MULTICS like to send \r without * \n; since we must turn off CRMOD to get proper * input, the mapping is done here (sigh). @@ -1726,6 +1716,10 @@ telrcv() if ((c == '\r') && my_want_state_is_dont(TELOPT_BINARY)) { if (scc > 0) { c = *sbp&0xff; +#if defined(ENCRYPTION) + if (decrypt_input) + c = (*decrypt_input)(c); +#endif if (c == 0) { sbp++, scc--; count++; /* a "true" CR */ @@ -1735,7 +1729,10 @@ telrcv() sbp++, scc--; count++; TTYADD('\n'); } else { - +#if defined(ENCRYPTION) + if (decrypt_input) + (*decrypt_input)(-1); +#endif TTYADD('\r'); if (crmod) { TTYADD('\n'); @@ -2171,7 +2168,7 @@ telnet(user) { sys_telnet_init(); -#if defined(AUTHENTICATION) +#if defined(AUTHENTICATION) || defined(ENCRYPTION) { static char local_host[256] = { 0 }; @@ -2182,13 +2179,17 @@ telnet(user) auth_encrypt_init(local_host, hostname, "TELNET", 0); auth_encrypt_user(user); } -#endif /* defined(AUTHENTICATION) */ +#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ # if !defined(TN3270) if (telnetport) { #if defined(AUTHENTICATION) if (autologin) send_will(TELOPT_AUTHENTICATION, 1); #endif +#if defined(ENCRYPTION) + send_do(TELOPT_ENCRYPT, 1); + send_will(TELOPT_ENCRYPT, 1); +#endif send_do(TELOPT_SGA, 1); send_will(TELOPT_TTYPE, 1); send_will(TELOPT_NAWS, 1); @@ -2199,8 +2200,8 @@ telnet(user) send_do(TELOPT_STATUS, 1); if (env_getvalue((unsigned char *)"DISPLAY")) send_will(TELOPT_XDISPLOC, 1); - if (eight) - tel_enter_binary(eight); + if (binary) + tel_enter_binary(binary); } # endif /* !defined(TN3270) */ |