summaryrefslogtreecommitdiffstats
path: root/src/appl
diff options
context:
space:
mode:
authorTom Yu <tlyu@mit.edu>2004-11-15 21:25:41 +0000
committerTom Yu <tlyu@mit.edu>2004-11-15 21:25:41 +0000
commit7e47f7162cb6fe83e269e9ddc3602b2869a46c90 (patch)
tree476e3a142b1a48c5fcdb9457c7a491d6f91a7972 /src/appl
parentafdca1d03a20d907d6e00bc31a69423a0c969ad9 (diff)
Merge Athena changes for requiring encrypted connections
ticket: 841 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16866 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/appl')
-rw-r--r--src/appl/telnet/libtelnet/ChangeLog5
-rw-r--r--src/appl/telnet/libtelnet/auth-proto.h3
-rw-r--r--src/appl/telnet/libtelnet/auth.c33
-rw-r--r--src/appl/telnet/telnetd/ChangeLog12
-rw-r--r--src/appl/telnet/telnetd/ext.h4
-rw-r--r--src/appl/telnet/telnetd/telnetd.813
-rw-r--r--src/appl/telnet/telnetd/telnetd.c48
-rw-r--r--src/appl/telnet/telnetd/utility.c61
8 files changed, 149 insertions, 30 deletions
diff --git a/src/appl/telnet/libtelnet/ChangeLog b/src/appl/telnet/libtelnet/ChangeLog
index 9e5c888d7..3467422dd 100644
--- a/src/appl/telnet/libtelnet/ChangeLog
+++ b/src/appl/telnet/libtelnet/ChangeLog
@@ -1,3 +1,8 @@
+2004-11-15 Tom Yu <tlyu@mit.edu>
+
+ * auth-proto.h, auth.c: Merge Athena changes for requiring
+ encrypted connections.
+
2004-06-04 Ken Raeburn <raeburn@mit.edu>
* Makefile.in (LIBBASE): Renamed from LIB.
diff --git a/src/appl/telnet/libtelnet/auth-proto.h b/src/appl/telnet/libtelnet/auth-proto.h
index 68cae7efc..6b4957032 100644
--- a/src/appl/telnet/libtelnet/auth-proto.h
+++ b/src/appl/telnet/libtelnet/auth-proto.h
@@ -67,7 +67,8 @@ void auth_send_retry (void);
void auth_is (unsigned char *, int);
void auth_reply (unsigned char *, int);
void auth_finished (Authenticator *, int);
-int auth_wait (char *);
+void auth_wait (char *);
+int auth_check (char *);
int auth_must_encrypt (void);
void auth_disable_name (char *);
void auth_gen_printsub (unsigned char *, int, unsigned char *, unsigned int);
diff --git a/src/appl/telnet/libtelnet/auth.c b/src/appl/telnet/libtelnet/auth.c
index 9c1b0b0fc..28b8ae8d1 100644
--- a/src/appl/telnet/libtelnet/auth.c
+++ b/src/appl/telnet/libtelnet/auth.c
@@ -85,6 +85,7 @@
int auth_debug_mode = 0;
int auth_has_failed = 0;
int auth_enable_encrypt = 0;
+int auth_client_non_unix = 0;
static char *Name = "Noname";
static int Server = 0;
static Authenticator *authenticated = 0;
@@ -337,15 +338,28 @@ auth_request()
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);
+ if (ap->type == AUTHTYPE_KERBEROS_V4 ||
+ !auth_client_non_unix) {
+ if (auth_debug_mode) {
+ printf(">>>%s: Sending type %d %d\r\n",
+ Name, ap->type, ap->way);
+ }
+ *e++ = ap->type;
+ *e++ = ap->way;
}
- *e++ = ap->type;
- *e++ = ap->way;
}
++ap;
}
+ if (auth_client_non_unix) {
+ ap = authenticators;
+ while (ap->type) {
+ if (i_support & ~i_wont_support & typemask(ap->type)) {
+ *e++ = ap->type;
+ *e++ = ap->way;
+ }
+ ++ap;
+ }
+ }
*e++ = IAC;
*e++ = SE;
net_write(str_request, e - str_request);
@@ -562,7 +576,7 @@ auth_intr(sig)
auth_finished(0, AUTH_REJECT);
}
- int
+ void
auth_wait(name)
char *name;
{
@@ -570,7 +584,7 @@ auth_wait(name)
printf(">>>%s: in auth_wait.\r\n", Name);
if (Server && !authenticating)
- return(0);
+ return;
(void) signal(SIGALRM, auth_intr);
alarm(30);
@@ -579,7 +593,12 @@ auth_wait(name)
break;
alarm(0);
(void) signal(SIGALRM, SIG_DFL);
+}
+ int
+auth_check(name)
+ char *name;
+{
/*
* Now check to see if the user is valid or not
*/
diff --git a/src/appl/telnet/telnetd/ChangeLog b/src/appl/telnet/telnetd/ChangeLog
index 1902a32f7..760cbb23f 100644
--- a/src/appl/telnet/telnetd/ChangeLog
+++ b/src/appl/telnet/telnetd/ChangeLog
@@ -1,3 +1,15 @@
+2004-11-15 Tom Yu <tlyu@mit.edu>
+
+ * ext.h: New variable "must_encrypt".
+
+ * telnetd.8: Update for changed command-line options.
+
+ * telnetd.c (getterminaltype): Merge Athena changes to require
+ encrypted connections.
+
+ * utility.c (ttsuck): Merge Athena changes to work around some
+ client timing bugs.
+
2004-09-22 Tom Yu <tlyu@mit.edu>
* Makefile.in (telnetd): Use UTIL_LIB.
diff --git a/src/appl/telnet/telnetd/ext.h b/src/appl/telnet/telnetd/ext.h
index 9fe38ef8b..7b77a44b0 100644
--- a/src/appl/telnet/telnetd/ext.h
+++ b/src/appl/telnet/telnetd/ext.h
@@ -88,6 +88,10 @@ extern char *unptyip; /* pointer to remaining characters in buffer */
extern int pty, net;
extern int SYNCHing; /* we are in TELNET SYNCH mode */
+#ifdef ENCRYPTION
+extern int must_encrypt;
+#endif
+
extern void
_termstat (void),
add_slc (int, int, int),
diff --git a/src/appl/telnet/telnetd/telnetd.8 b/src/appl/telnet/telnetd/telnetd.8
index 9426a0c3b..78700cbed 100644
--- a/src/appl/telnet/telnetd/telnetd.8
+++ b/src/appl/telnet/telnetd/telnetd.8
@@ -39,7 +39,7 @@ protocol server
.SH SYNOPSIS
.B /usr/libexec/telnetd
[\fB\-a\fP \fIauthmode\fP] [\fB\-B\fP] [\fB\-D\fP] [\fIdebugmode\fP]
-[\fB\-edebug\fP] [\fB\-h\fP] [\fB\-I\fP\fIinitid\fP] [\fB\-l\fP]
+[\fB\-e\fP] [\fB\-h\fP] [\fB\-I\fP\fIinitid\fP] [\fB\-l\fP]
[\fB\-k\fP] [\fB\-n\fP] [\fB\-r\fP\fIlowpty-highpty\fP] [\fB\-s\fP]
[\fB\-S\fP \fItos\fP] [\fB\-U\fP] [\fB\-X\fP \fIauthtype\fP]
[\fB\-w\fP [\fBip\fP|\fImaxhostlen\fP[\fB,\fP[\fBno\fP]\fBstriplocal\fP]]]
@@ -163,6 +163,9 @@ Displays the data stream received by
.B ptydata
Displays data written to the pty.
.TP
+.B encrypt
+Enables encryption debugging code.
+.TP
.B exercise
Has not been implemented yet.
.RE
@@ -175,12 +178,10 @@ Enables debugging on each socket created by
in
.IR socket (2)).
.TP
-.B \-edebug
-If
+.B \-e
+This option causes
.B telnetd
-has been compiled with support for data encryption, then the
-.B edebug
-option may be used to enable encryption debugging code.
+to refuse unencrypted connections.
.TP
.B \-h
Disables the printing of host-specific information before login has been
diff --git a/src/appl/telnet/telnetd/telnetd.c b/src/appl/telnet/telnetd/telnetd.c
index 5633d5625..a90fa5c5c 100644
--- a/src/appl/telnet/telnetd/telnetd.c
+++ b/src/appl/telnet/telnetd/telnetd.c
@@ -173,7 +173,7 @@ char valid_opts[] = {
'D', ':',
#endif
#ifdef ENCRYPTION
- 'e', ':',
+ 'e',
#endif
#if defined(CRAY) && defined(NEWINIT)
'I', ':',
@@ -308,6 +308,9 @@ main(argc, argv)
diagnostic |= TD_PTYDATA;
} else if (!strcmp(optarg, "options")) {
diagnostic |= TD_OPTIONS;
+ } else if (!strcmp(optarg, "encrypt")) {
+ extern int encrypt_debug_mode;
+ encrypt_debug_mode = 1;
} else {
usage();
/* NOT REACHED */
@@ -317,13 +320,7 @@ main(argc, argv)
#ifdef ENCRYPTION
case 'e':
- if (strcmp(optarg, "debug") == 0) {
- extern int encrypt_debug_mode;
- encrypt_debug_mode = 1;
- break;
- }
- usage();
- /* NOTREACHED */
+ must_encrypt = 1;
break;
#endif /* ENCRYPTION */
@@ -694,8 +691,12 @@ usage()
static void encrypt_failure()
{
- char *lerror_message =
- "Encryption was not successfully negotiated. Goodbye.\r\n\r\n";
+ char *lerror_message;
+
+ if (auth_must_encrypt())
+ lerror_message = "Encryption was not successfully negotiated. Goodbye.\r\n\r\n";
+ else
+ lerror_message = "Unencrypted connection refused. Goodbye.\r\n\r\n";
netputs(lerror_message);
netflush();
@@ -720,6 +721,7 @@ getterminaltype(name)
settimer(baseline);
#if defined(AUTHENTICATION)
+ ttsuck();
/*
* Handle the Authentication option before we do anything else.
*/
@@ -727,7 +729,7 @@ getterminaltype(name)
while (his_will_wont_is_changing(TELOPT_AUTHENTICATION))
ttloop();
if (his_state_is_will(TELOPT_AUTHENTICATION)) {
- retval = auth_wait(name);
+ auth_wait(name);
}
#endif
@@ -760,15 +762,25 @@ getterminaltype(name)
if (his_state_is_will(TELOPT_ENCRYPT)) {
encrypt_wait();
}
- if (auth_must_encrypt()) {
+ if (must_encrypt || auth_must_encrypt()) {
time_t timeout = time(0) + 60;
if (my_state_is_dont(TELOPT_ENCRYPT) ||
- my_state_is_wont(TELOPT_ENCRYPT))
+ my_state_is_wont(TELOPT_ENCRYPT) ||
+ his_state_is_wont(TELOPT_AUTHENTICATION))
encrypt_failure();
- if (!EncryptStartInput() || !EncryptStartOutput())
- encrypt_failure();
+ while (!EncryptStartInput()) {
+ if (time (0) > timeout)
+ encrypt_failure();
+ ttloop();
+ }
+
+ while (!EncryptStartOutput()) {
+ if (time (0) > timeout)
+ encrypt_failure();
+ ttloop();
+ }
while (!encrypt_is_encrypting()) {
if (time(0) > timeout)
@@ -865,7 +877,11 @@ getterminaltype(name)
}
}
}
- return(retval);
+#ifdef AUTHENTICATION
+ return(auth_check(name));
+#else
+ return(-1);
+#endif
} /* end of getterminaltype */
static void
diff --git a/src/appl/telnet/telnetd/utility.c b/src/appl/telnet/telnetd/utility.c
index fc8ff7601..f4568ec28 100644
--- a/src/appl/telnet/telnetd/utility.c
+++ b/src/appl/telnet/telnetd/utility.c
@@ -90,6 +90,67 @@ read_again:
}
} /* end of ttloop */
+/*
+ * ttsuck - This is a horrible kludge to deal with a bug in
+ * HostExplorer. HostExplorer thinks it knows how to do krb5 auth, but
+ * it doesn't really. So if you offer it krb5 as an auth choice before
+ * krb4, it will sabotage the connection. So we peek ahead into the
+ * input stream to see if the client is a UNIX client, and then
+ * (later) offer krb5 first only if it is. Since no Mac/PC telnet
+ * clients do auto switching between krb4 and krb5 like the UNIX
+ * client does, it doesn't matter what order they see the choices in
+ * (except for HostExplorer).
+ *
+ * It is actually not possible to do this without looking ahead into
+ * the input stream: the client and server both try to begin
+ * auth/encryption negotiation as soon as possible, so if we let the
+ * server process things normally, it will already have sent the list
+ * of supported auth types before seeing the NEW-ENVIRON option. If
+ * you change the code to hold off sending the list of supported auth
+ * types until after it knows whether or not the remote side supports
+ * NEW-ENVIRON, then the auth negotiation and encryption negotiation
+ * race conditions won't interact properly, and encryption negotiation
+ * will reliably fail.
+ */
+
+ void
+ttsuck()
+{
+ extern int auth_client_non_unix;
+ int nread;
+ struct timeval tv;
+ fd_set fds;
+ char *p, match[] = {IAC, WILL, TELOPT_NEW_ENVIRON};
+
+ if (nfrontp-nbackp) {
+ netflush();
+ }
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ FD_SET(net, &fds);
+
+ while (select(net + 1, &fds, NULL, NULL, &tv) == 1)
+ {
+ nread = read(net, netibuf + ncc, sizeof(netibuf) - ncc);
+ if (nread <= 0)
+ break;
+ ncc += nread;
+ }
+
+ auth_client_non_unix = 1;
+ for (p = netibuf; p < netibuf + ncc; p++)
+ {
+ if (!memcmp(p, match, sizeof(match)))
+ {
+ auth_client_non_unix = 0;
+ break;
+ }
+ }
+
+ if (ncc > 0)
+ telrcv();
+}
+
/*
* Check a descriptor to see if out of band data exists on it.
*/