NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/58787: telnetd(8): asks for auth twice with `-a off'; autologin doesn't work w/o SRA-auth



>Number:         58787
>Category:       bin
>Synopsis:       telnetd(8): asks for auth twice with `-a off'; autologin doesn't work w/o SRA-auth
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Oct 29 09:30:01 +0000 2024
>Originator:     RVP
>Release:        NetBSD/amd64 10.99.12
>Organization:
>Environment:
NetBSD/amd64 10.99.12
>Description:
1. When telnetd(8) is run with `-a off', it should not negotiate
   any authentication, but it does, leading to this when the client
   does SRA auth by default (like the *BSD telnets):

   - Start server with `-a off':
```
root# /usr/libexec/telnetd -a off -debug
```

   - Run SRA-enabled client:
```
$ telnet localhost
Trying ::1...
telnet: Connect to address ::1: : Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Trying SRA secure login:
User (rvp):
Password:
[ SRA accepts you ]

NetBSD/amd64 (CoreBook.local) (pts/5)

login: rvp
Password for rvp@CoreBook.local:
Last login: Tue Oct 29 08:30:00 2024 from localhost on pts/5
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
    2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
    2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023,
    2024
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 10.99.12 (COREBOOK_DIAG) #0: Tue Oct 29 00:55:04 UTC 2024

Welcome to NetBSD!

This is a development snapshot of NetBSD for testing -- user beware!

Bug reports: https://www.NetBSD.org/support/send-pr.html
Donations to the NetBSD Foundation: https://www.NetBSD.org/donations/
$
```

   One has to either,
    a) enter the username/password twice, or
    b) run `telnet -X sra' to disable SRA connections.

   Both are are a pain.


2. Auto-login doesn't work without SRA-auth. This is independent of 1).
   See also PR bin/21450 where this is fixed slightly differently.

   Fixes for 1) and 2) are mostly FreeBSD's:

   https://github.com/freebsd/freebsd-src/commit/2e3838552652a5dbb8a6ca0d5b25799f8e90dd98
   https://github.com/freebsd/freebsd-src/commit/f2e6a017d58cdb1daf75da562ac34a61230e385a


3. Make the extern var. `encrypt_debug_mode' static by re-using a
   redundant function encrypt_debug() to now retrieve that value.
   EncryptDebug() already does what encrypt_debug() did.

Thx,
-RVP

>How-To-Repeat:
As above.
>Fix:
--START patch--
diff -urN a/src/lib/libtelnet/enc-proto.h b/src/lib/libtelnet/enc-proto.h
--- a/src/lib/libtelnet/enc-proto.h	2019-01-05 08:55:58.000000000 +0000
+++ b/src/lib/libtelnet/enc-proto.h	2024-10-29 07:09:36.992996030 +0000
@@ -73,6 +73,7 @@
 int EncryptVerbose(int);
 int EncryptAutoEnc(int);
 int EncryptAutoDec(int);
+int encrypt_debug(void);
 void encrypt_support(unsigned char *, int);
 void encrypt_is(unsigned char *, int);
 void encrypt_reply(unsigned char *, int);
@@ -93,7 +94,6 @@
 void encrypt_send_request_start(void);
 void encrypt_send_request_end(void);
 void encrypt_wait(void);
-void encrypt_debug(int);
 void encrypt_gen_printsub(unsigned char *, int, unsigned char *, int );
 void encrypt_printsub(unsigned char *, int, unsigned char *, int );
 
diff -urN a/src/lib/libtelnet/enc_des.c b/src/lib/libtelnet/enc_des.c
--- a/src/lib/libtelnet/enc_des.c	2024-09-08 09:36:47.000000000 +0000
+++ b/src/lib/libtelnet/enc_des.c	2024-10-29 07:10:20.520083047 +0000
@@ -201,7 +201,7 @@
 		}
 		state &= ~NO_SEND_IV;
 		state |= NO_RECV_IV;
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf("Creating new feed\r\n");
 		/*
 		 * Create a random feed and send it over.
@@ -257,16 +257,16 @@
 	switch (*data++) {
 	case FB64_IV:
 		if (cnt != sizeof(Block)) {
-			if (encrypt_debug_mode)
+			if (encrypt_debug())
 				printf("CFB64: initial vector failed on size\r\n");
 			state = FAILED;
 			goto failure;
 		}
 
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf("CFB64: initial vector received\r\n");
 
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf("Initializing Decrypt stream\r\n");
 
 		fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]);
@@ -284,7 +284,7 @@
 		break;
 
 	default:
-		if (encrypt_debug_mode) {
+		if (encrypt_debug()) {
 			printf("Unknown option type: %d\r\n", *(data-1));
 			printd(data, cnt);
 			printf("\r\n");
@@ -351,7 +351,7 @@
 		break;
 
 	default:
-		if (encrypt_debug_mode) {
+		if (encrypt_debug()) {
 			printf("Unknown option type: %d\r\n", data[-1]);
 			printd(data, cnt);
 			printf("\r\n");
@@ -381,7 +381,7 @@
 {
 
 	if (!key || key->type != SK_DES) {
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf("Can't set krbdes's session key (%d != %d)\r\n",
 				key ? key->type : -1, SK_DES);
 		return;
diff -urN a/src/lib/libtelnet/encrypt.c b/src/lib/libtelnet/encrypt.c
--- a/src/lib/libtelnet/encrypt.c	2022-02-23 21:54:40.000000000 +0000
+++ b/src/lib/libtelnet/encrypt.c	2024-10-29 08:15:38.194507307 +0000
@@ -79,7 +79,7 @@
 void	(*encrypt_output)(unsigned char *, int);
 int	(*decrypt_input)(int);
 
-int encrypt_debug_mode = 0;
+static int encrypt_debug_mode = 0;
 static int decrypt_mode = 0;
 static int encrypt_mode = 0;
 static int encrypt_verbose = 0;
@@ -192,7 +192,7 @@
 	str_suplen = 4;
 
 	while (ep->type) {
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf(">>>%s: I will support %s\r\n",
 				Name, ENCTYPE_NAME(ep->type));
 		i_support_encrypt |= typemask(ep->type);
@@ -483,7 +483,7 @@
 
 	while (cnt-- > 0) {
 		type = *typelist++;
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf(">>>%s: He is supporting %s (%d)\r\n",
 				Name,
 				ENCTYPE_NAME(type), type);
@@ -499,7 +499,7 @@
 		if (!ep)
 			return;
 		type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0;
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf(">>>%s: (*ep->start)() returned %d\r\n",
 					Name, type);
 		if (type < 0)
@@ -522,7 +522,7 @@
 	if (type < ENCTYPE_CNT)
 		remote_supports_encrypt |= typemask(type);
 	if (!(ep = finddecryption(type))) {
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
 				Name,
 				ENCTYPE_NAME_OK(type)
@@ -531,7 +531,7 @@
 		return;
 	}
 	if (!ep->is) {
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n",
 				Name,
 				ENCTYPE_NAME_OK(type)
@@ -540,7 +540,7 @@
 		ret = 0;
 	} else {
 		ret = (*ep->is)(data, cnt);
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf("(*ep->is)(%p, %d) returned %s(%d)\n", data, cnt,
 				(ret < 0) ? "FAIL " :
 				(ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
@@ -564,7 +564,7 @@
 		return;
 	type = *data++;
 	if (!(ep = findencryption(type))) {
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
 				Name,
 				ENCTYPE_NAME_OK(type)
@@ -573,7 +573,7 @@
 		return;
 	}
 	if (!ep->reply) {
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n",
 				Name,
 				ENCTYPE_NAME_OK(type)
@@ -582,13 +582,13 @@
 		ret = 0;
 	} else {
 		ret = (*ep->reply)(data, cnt);
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf("(*ep->reply)(%p, %d) returned %s(%d)\n",
 				data, cnt,
 				(ret < 0) ? "FAIL " :
 				(ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
 	}
-	if (encrypt_debug_mode)
+	if (encrypt_debug())
 		printf(">>>%s: encrypt_reply returned %d\n", Name, ret);
 	if (ret < 0) {
 		autoencrypt = 0;
@@ -624,7 +624,7 @@
 		if (encrypt_verbose)
 			printf("[ Input is now decrypted with type %s ]\r\n",
 				ENCTYPE_NAME(decrypt_mode));
-		if (encrypt_debug_mode)
+		if (encrypt_debug())
 			printf(">>>%s: Start to decrypt input with type %s\r\n",
 				Name, ENCTYPE_NAME(decrypt_mode));
 	} else {
@@ -665,7 +665,7 @@
 encrypt_end(void)
 {
 	decrypt_input = 0;
-	if (encrypt_debug_mode)
+	if (encrypt_debug())
 		printf(">>>%s: Input is back to clear text\r\n", Name);
 	if (encrypt_verbose)
 		printf("[ Input is now clear text ]\r\n");
@@ -803,7 +803,7 @@
 	register int i;
 
 	if (!(ep = findencryption(type))) {
-		if (encrypt_debug_mode) {
+		if (encrypt_debug()) {
 			printf(">>>%s: Can't encrypt with type %s (%d)\r\n",
 				Name,
 				ENCTYPE_NAME_OK(type)
@@ -814,7 +814,7 @@
 	}
 	if (ep->start) {
 		i = (*ep->start)(DIR_ENCRYPT, Server);
-		if (encrypt_debug_mode) {
+		if (encrypt_debug()) {
 			printf(">>>%s: Encrypt start: %s (%d) %s\r\n",
 				Name,
 				(i < 0) ? "failed" :
@@ -843,7 +843,7 @@
 	 */
 	encrypt_output = ep->output;
 	encrypt_mode = type;
-	if (encrypt_debug_mode)
+	if (encrypt_debug())
 		printf(">>>%s: Started to encrypt output with type %s\r\n",
 			Name, ENCTYPE_NAME(type));
 	if (encrypt_verbose)
@@ -866,7 +866,7 @@
 	 * netflush...
 	 */
 	encrypt_output = 0;
-	if (encrypt_debug_mode)
+	if (encrypt_debug())
 		printf(">>>%s: Output is back to clear text\r\n", Name);
 	if (encrypt_verbose)
 		printf("[ Output is now clear text ]\r\n");
@@ -888,7 +888,7 @@
 	*p++ = SE;
 	telnet_net_write(str_start, p - str_start);
 	printsub('>', &str_start[2], p - &str_start[2]);
-	if (encrypt_debug_mode)
+	if (encrypt_debug())
 		printf(">>>%s: Request input to be encrypted\r\n", Name);
 }
 
@@ -899,14 +899,14 @@
 	telnet_net_write(str_end, sizeof(str_end));
 	printsub('>', &str_end[2], sizeof(str_end) - 2);
 
-	if (encrypt_debug_mode)
+	if (encrypt_debug())
 		printf(">>>%s: Request input to be clear text\r\n", Name);
 }
 
 void
 encrypt_wait(void)
 {
-	if (encrypt_debug_mode)
+	if (encrypt_debug())
 		printf(">>>%s: in encrypt_wait\r\n", Name);
 	if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt))
 		return;
@@ -915,10 +915,10 @@
 			return;
 }
 
-void
-encrypt_debug(int mode)
+int
+encrypt_debug(void)
 {
-	encrypt_debug_mode = mode;
+	return encrypt_debug_mode;
 }
 
 void
diff -urN a/src/lib/libtelnet/encrypt.h b/src/lib/libtelnet/encrypt.h
--- a/src/lib/libtelnet/encrypt.h	2012-01-09 15:25:33.000000000 +0000
+++ b/src/lib/libtelnet/encrypt.h	2024-10-29 07:15:33.170109450 +0000
@@ -94,7 +94,6 @@
 
 #include "enc-proto.h"
 
-extern int encrypt_debug_mode;
 extern int (*decrypt_input)(int);
 extern void (*encrypt_output)(unsigned char *, int);
 # endif /* __ENCRYPTION__ */
diff -urN a/src/libexec/telnetd/state.c b/src/libexec/telnetd/state.c
--- a/src/libexec/telnetd/state.c	2024-02-11 02:25:05.774588529 +0000
+++ b/src/libexec/telnetd/state.c	2024-10-29 06:34:36.254698800 +0000
@@ -549,8 +549,10 @@
 
 #ifdef	AUTHENTICATION
 		case TELOPT_AUTHENTICATION:
-			func = auth_request;
-			changeok++;
+			if (auth_level >= 0) {
+				func = auth_request;
+				changeok++;
+			}
 			break;
 #endif
 
diff -urN a/src/libexec/telnetd/sys_term.c b/src/libexec/telnetd/sys_term.c
--- a/src/libexec/telnetd/sys_term.c	2019-08-15 01:15:21.000000000 +0000
+++ b/src/libexec/telnetd/sys_term.c	2024-10-29 07:00:45.073609456 +0000
@@ -583,6 +583,10 @@
 	const char *loginprog = NULL;
 	extern struct sockaddr_storage from;
 	char buf[sizeof(from) * 4 + 1];
+	char *user;
+
+	user = getenv("USER");
+	user = (user != NULL) ? strdup(user) : NULL;
 
 	scrub_env();
 
@@ -634,9 +638,9 @@
 		argv = addarg(argv, name);
 	} else
 #endif
-	if (getenv("USER")) {
+	if (user != NULL) {
 		argv = addarg(argv, "--");
-		argv = addarg(argv, getenv("USER"));
+		argv = addarg(argv, user);
 		/*
 		 * Assume that login will set the USER variable
 		 * correctly.  For SysV systems, this means that
diff -urN a/src/libexec/telnetd/telnetd.c b/src/libexec/telnetd/telnetd.c
--- a/src/libexec/telnetd/telnetd.c	2023-09-21 14:00:34.000000000 +0000
+++ b/src/libexec/telnetd/telnetd.c	2024-10-29 06:50:50.391238938 +0000
@@ -242,7 +242,7 @@
 #ifdef	ENCRYPTION
 		case 'e':
 			if (strcmp(optarg, "debug") == 0) {
-				encrypt_debug_mode = 1;
+				EncryptDebug(1);
 				break;
 			}
 			usage();
@@ -493,11 +493,13 @@
     /*
      * Handle the Authentication option before we do anything else.
      */
-    send_do(TELOPT_AUTHENTICATION, 1);
-    while (his_will_wont_is_changing(TELOPT_AUTHENTICATION))
-	ttloop();
-    if (his_state_is_will(TELOPT_AUTHENTICATION)) {
-	retval = auth_wait(name, l);
+    if (auth_level >= 0) {
+        send_do(TELOPT_AUTHENTICATION, 1);
+        while (his_will_wont_is_changing(TELOPT_AUTHENTICATION))
+    	    ttloop();
+        if (his_state_is_will(TELOPT_AUTHENTICATION)) {
+    	    retval = auth_wait(name, l);
+        }
     }
 #endif
 
--END patch--



Home | Main Index | Thread Index | Old Index