NetBSD-Bugs archive

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

bin/58790: telnetd(8): doesn't do PAM account mgmt with SRA-auth



>Number:         58790
>Category:       bin
>Synopsis:       telnetd(8): doesn't do PAM account mgmt with SRA-auth
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Oct 29 23:25:00 +0000 2024
>Originator:     RVP
>Release:        NetBSD/amd64 10.99.12
>Organization:
>Environment:
NetBSD/amd64 10.99.12
>Description:
telnetd(8) as it is compiled now uses PAM to authenticate the user if
SRA auth. is in use (when run with `-a valid'). However, no account
management is done at all even though the PAM config files for telnetd
specify pam_securetty.so and pam_login_access.so.

This leads to unexpected results:

1. Start server with SRA-auth
```
root# echo '-:rvp:ALL' > /etc/login.access	# bar `rvp'
root# /usr/libexec/telnetd -a valid -debug
```

2. Connect as `rvp' (should fail)
```
$ telnet -l rvp 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/2)

Last login: Tue Oct 29 21:54:00 2024 from localhost on pts/2
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) #0: Tue Oct 29 00:49:39 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/
$
```
Connection succeeds!

If possible, please close PR bin/29720 too.

Also, while there's a man-page, login.access(5), there's no template
file in /etc. FreeBSD has one here:

https://github.com/freebsd/freebsd-src/blob/main/usr.bin/login/login.access

(I spent a good half-an-hour wondering why `EXCEPT localhost' didn't
work before I figured out--by reading the source--that the correct
phrase is `ALL EXCEPT localhost'.)

>How-To-Repeat:
As shown above.
>Fix:
--START patch--
diff -urN lib/libtelnet.orig/sra.c lib/libtelnet/sra.c
--- lib/libtelnet.orig/sra.c	2021-10-30 10:46:57.000000000 +0000
+++ lib/libtelnet/sra.c	2024-10-29 22:39:44.142414360 +0000
@@ -148,7 +148,7 @@
 
 	if (auth_debug_mode)
 		printf("Sent PKA to server.\r\n" );
-	printf("Trying SRA secure login:\r\n");
+	printf("Trying SRA secure login...\r\n");
 	if (!Data(ap, SRA_KEY, (void *)pka, HEXKEYBYTES)) {
 		if (auth_debug_mode)
 			printf("Not enough room for authentication data\r\n");
@@ -314,7 +314,7 @@
 	case SRA_CONTINUE:
 		if (passwd_sent) {
 			passwd_sent = 0;
-			printf("[ SRA login failed ]\r\n");
+			printf("[ SRA login failed/not allowed ]\r\n");
 			goto enc_user;
 		}
 		if (cnt > XSMALL_LEN - 1) { 
@@ -345,7 +345,7 @@
 
 	case SRA_REJECT:
 		printf("[ SRA refuses authentication ]\r\n");
-		printf("Trying plaintext login:\r\n");
+		printf("Trying plaintext login...\r\n");
 		auth_finished(0, AUTH_REJECT);
 		return;
 
@@ -558,7 +558,7 @@
 {
 	pam_handle_t *pamh = NULL;
 	const void *item;
-	int rval;
+	int rval = 0;			/* default: fail */
 	int e;
 	cred_t auth_cred = { name, cred };
 	struct pam_conv conv = { &auth_conv, &auth_cred };
@@ -581,6 +581,12 @@
 	e = pam_authenticate(pamh, 0);
 	switch (e) {
 	case PAM_SUCCESS:
+		if ((e = pam_get_item(pamh, PAM_USER, &item)) != 
+		    PAM_SUCCESS) {
+			syslog(LOG_ERR, "Couldn't get PAM_USER: %s",
+			pam_strerror(pamh, e));
+			break;		/* switch */
+		}
 		/*
 		 * With PAM we support the concept of a "template"
 		 * user.  The user enters a login name which is
@@ -598,36 +604,41 @@
 		 * point of view, the template user is always passed
 		 * back as a changed value of the PAM_USER item.
 		 */
-		if ((e = pam_get_item(pamh, PAM_USER, &item)) == 
-		    PAM_SUCCESS) {
-			strlcpy(name, item, SMALL_LEN);
-		} else
-			syslog(LOG_ERR, "Couldn't get PAM_USER: %s",
-			pam_strerror(pamh, e));
-#if 0	/* pam_securetty(8) should be used to enforce this */
-		if (isroot(name) && !rootterm(line))
-			rval = 0;
-		else
-#endif
-			rval = 1;
-		break;
+		strlcpy(name, item, SMALL_LEN);
+		switch (pam_acct_mgmt(pamh, 0)) {
+		case PAM_SUCCESS:
+			rval = 1;	/* Yes! */
+			break;
+		case PAM_NEW_AUTHTOK_REQD:
+			e = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+			if (e != PAM_SUCCESS)
+				syslog(LOG_ERR, "pam_chauthtok failed: %s",
+				    pam_strerror(pamh, e));
+			break;
+		case PAM_AUTH_ERR:
+		case PAM_USER_UNKNOWN:
+		case PAM_MAXTRIES:
+			break;
+		default:
+			syslog(LOG_ERR, "pam_acct_mgmt error: %s",
+			    pam_strerror(pamh, e));
+			break;		/* pam_acct_mgmt */
+		}
+		break;			/* pam_authenticate */
 
 	case PAM_AUTH_ERR:
 	case PAM_USER_UNKNOWN:
 	case PAM_MAXTRIES:
-		rval = 0;
-	break;
+		break;
 
 	default:
 		syslog(LOG_ERR, "auth_pam: %s", pam_strerror(pamh, e));
-		rval = 0;
 		break;
 	}
 
-	if ((e = pam_end(pamh, e)) != PAM_SUCCESS) {
+	if ((e = pam_end(pamh, e)) != PAM_SUCCESS)
 		syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
-		rval = 0;
-	}
+
 	return rval;
 }
 
--END patch--



Home | Main Index | Thread Index | Old Index