summaryrefslogtreecommitdiff
path: root/usr.bin/telnet/telnet.c
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>1998-03-12 04:57:48 +0000
committerArtur Grabowski <art@cvs.openbsd.org>1998-03-12 04:57:48 +0000
commitff07d4940bd49261ee22ce0ace862e5589593044 (patch)
treef425ce5c7200ee7aba8c8aef0e45753733167523 /usr.bin/telnet/telnet.c
parentdc9f07b18d9385c5d9662784d3fd1ac69b5c271a (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.c249
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) */