Module Name: src Committed By: martin Date: Mon Nov 18 19:44:57 UTC 2024
Modified Files: src/lib/libtelnet [netbsd-9]: enc-proto.h enc_des.c encrypt.c encrypt.h src/libexec/telnetd [netbsd-9]: state.c sys_term.c telnetd.c Log Message: Pull up following revision(s) (requested by riastradh in ticket #1927): lib/libtelnet/encrypt.h: revision 1.10 libexec/telnetd/telnetd.c: revision 1.59 libexec/telnetd/sys_term.c: revision 1.50 lib/libtelnet/encrypt.c: revision 1.20 lib/libtelnet/enc_des.c: revision 1.18 lib/libtelnet/enc-proto.h: revision 1.11 libexec/telnetd/state.c: revision 1.33 libexec/telnetd/state.c: revision 1.35 libexec/telnetd/telnetd.c: revision 1.60 Fix memory leak - free resources allocated by getaddrinfo Fix off by one in telrcv() In case of "\r" in the data buffer, the code was unconditionally looking ahead to next character, even if "\r" was last character in the buffer. That condition leads to read outside of the data (one byte after the array) Thanks christos@ for the review PR bin/58787 libtelnet - avoid using a global variable >From RVP -- make 'encrypt_debug_mode' be a static (file scope) variable instead of extern, and convert the (had been recently anyway) unused function encrypt_debug() into an accensor function for it. This is the minor (almost irrelevant) change from PR bin/58787 PR bin/58787 telnetd - handle auto authentication better Apparently from FreeBSD via RVP -- but FreeBSD deleted telnetd more than 2 years ago, so I assume instead from https://github.com/cschuber/freebsd-telnet/tree/main/contrib/telnet To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.10.2.1 src/lib/libtelnet/enc-proto.h cvs rdiff -u -r1.16 -r1.16.34.1 src/lib/libtelnet/enc_des.c cvs rdiff -u -r1.18 -r1.18.2.1 src/lib/libtelnet/encrypt.c cvs rdiff -u -r1.9 -r1.9.42.1 src/lib/libtelnet/encrypt.h cvs rdiff -u -r1.31 -r1.31.2.1 src/libexec/telnetd/state.c cvs rdiff -u -r1.48.2.1 -r1.48.2.2 src/libexec/telnetd/sys_term.c cvs rdiff -u -r1.55.28.2 -r1.55.28.3 src/libexec/telnetd/telnetd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libtelnet/enc-proto.h diff -u src/lib/libtelnet/enc-proto.h:1.10 src/lib/libtelnet/enc-proto.h:1.10.2.1 --- src/lib/libtelnet/enc-proto.h:1.10 Sat Jan 5 08:55:58 2019 +++ src/lib/libtelnet/enc-proto.h Mon Nov 18 19:44:57 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: enc-proto.h,v 1.10 2019/01/05 08:55:58 maya Exp $ */ +/* $NetBSD: enc-proto.h,v 1.10.2.1 2024/11/18 19:44:57 martin Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -73,6 +73,7 @@ int EncryptDebug(int); 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_end(void); 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 ); Index: src/lib/libtelnet/enc_des.c diff -u src/lib/libtelnet/enc_des.c:1.16 src/lib/libtelnet/enc_des.c:1.16.34.1 --- src/lib/libtelnet/enc_des.c:1.16 Wed Mar 21 05:33:27 2012 +++ src/lib/libtelnet/enc_des.c Mon Nov 18 19:44:57 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: enc_des.c,v 1.16 2012/03/21 05:33:27 matt Exp $ */ +/* $NetBSD: enc_des.c,v 1.16.34.1 2024/11/18 19:44:57 martin Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)enc_des.c 8.3 (Berkeley) 5/30/95"; */ #else -__RCSID("$NetBSD: enc_des.c,v 1.16 2012/03/21 05:33:27 matt Exp $"); +__RCSID("$NetBSD: enc_des.c,v 1.16.34.1 2024/11/18 19:44:57 martin Exp $"); #endif #endif /* not lint */ @@ -201,7 +201,7 @@ fb64_start(struct fb *fbp, int dir, int } 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 @@ fb64_is(unsigned char *data, int cnt, st 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 @@ fb64_is(unsigned char *data, int cnt, st 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 @@ fb64_reply(unsigned char *data, int cnt, 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 @@ fb64_session(Session_Key *key, int serve { 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; Index: src/lib/libtelnet/encrypt.c diff -u src/lib/libtelnet/encrypt.c:1.18 src/lib/libtelnet/encrypt.c:1.18.2.1 --- src/lib/libtelnet/encrypt.c:1.18 Sat Jan 5 08:55:58 2019 +++ src/lib/libtelnet/encrypt.c Mon Nov 18 19:44:57 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: encrypt.c,v 1.18 2019/01/05 08:55:58 maya Exp $ */ +/* $NetBSD: encrypt.c,v 1.18.2.1 2024/11/18 19:44:57 martin Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -33,7 +33,7 @@ #if 0 static char sccsid[] = "@(#)encrypt.c 8.2 (Berkeley) 5/30/95"; #else -__RCSID("$NetBSD: encrypt.c,v 1.18 2019/01/05 08:55:58 maya Exp $"); +__RCSID("$NetBSD: encrypt.c,v 1.18.2.1 2024/11/18 19:44:57 martin Exp $"); #endif /* not lint */ /* @@ -79,7 +79,7 @@ __RCSID("$NetBSD: encrypt.c,v 1.18 2019/ 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 @@ encrypt_init(const char *name, int serve 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 @@ encrypt_support(unsigned char *typelist, 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 @@ encrypt_support(unsigned char *typelist, 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 @@ encrypt_is(unsigned char *data, int cnt) 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 @@ encrypt_is(unsigned char *data, int cnt) 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 @@ encrypt_is(unsigned char *data, int cnt) 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 @@ encrypt_reply(unsigned char *data, int c 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 @@ encrypt_reply(unsigned char *data, int c 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 @@ encrypt_reply(unsigned char *data, int c 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 @@ encrypt_start(unsigned char *data, int c 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 @@ void 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 @@ encrypt_start_output(int type) 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 @@ encrypt_start_output(int type) } 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_start_output(int type) */ 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 @@ encrypt_send_end(void) * 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 @@ encrypt_send_request_start(void) *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 @@ encrypt_send_request_end(void) 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 @@ encrypt_wait(void) return; } -void -encrypt_debug(int mode) +int +encrypt_debug(void) { - encrypt_debug_mode = mode; + return encrypt_debug_mode; } void Index: src/lib/libtelnet/encrypt.h diff -u src/lib/libtelnet/encrypt.h:1.9 src/lib/libtelnet/encrypt.h:1.9.42.1 --- src/lib/libtelnet/encrypt.h:1.9 Mon Jan 9 15:25:33 2012 +++ src/lib/libtelnet/encrypt.h Mon Nov 18 19:44:57 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: encrypt.h,v 1.9 2012/01/09 15:25:33 christos Exp $ */ +/* $NetBSD: encrypt.h,v 1.9.42.1 2024/11/18 19:44:57 martin Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -94,7 +94,6 @@ typedef struct { #include "enc-proto.h" -extern int encrypt_debug_mode; extern int (*decrypt_input)(int); extern void (*encrypt_output)(unsigned char *, int); # endif /* __ENCRYPTION__ */ Index: src/libexec/telnetd/state.c diff -u src/libexec/telnetd/state.c:1.31 src/libexec/telnetd/state.c:1.31.2.1 --- src/libexec/telnetd/state.c:1.31 Sun Feb 3 03:19:25 2019 +++ src/libexec/telnetd/state.c Mon Nov 18 19:44:57 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: state.c,v 1.31 2019/02/03 03:19:25 mrg Exp $ */ +/* $NetBSD: state.c,v 1.31.2.1 2024/11/18 19:44:57 martin Exp $ */ /* * Copyright (c) 1989, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)state.c 8.5 (Berkeley) 5/30/95"; #else -__RCSID("$NetBSD: state.c,v 1.31 2019/02/03 03:19:25 mrg Exp $"); +__RCSID("$NetBSD: state.c,v 1.31.2.1 2024/11/18 19:44:57 martin Exp $"); #endif #endif /* not lint */ @@ -100,9 +100,33 @@ telrcv(void) case TS_CR: state = TS_DATA; - /* Strip off \n or \0 after a \r */ - if ((c == 0) || (c == '\n')) { - break; + +#ifdef LINEMODE + /* + * If we are operating in linemode, + * convert to local end-of-line. + */ + if (linemode && (ncc > 0) && ((c == '\n') || + ((c == 0) && tty_iscrnl())) ) + c = '\n'; + else +#endif + { + /* + * We now map \r\n ==> \r for pragmatic reasons. + * Many client implementations send \r\n when + * the user hits the CarriageReturn key. + * + * We USED to map \r\n ==> \n, since \r\n says + * that we want to be in column 1 of the next + * printable line, and \n is the standard + * unix way of saying that (\r is only good + * if CRMOD is set, which it normally is). + */ + + /* Strip off \n or \0 after a \r */ + if ((c == 0) || (c == '\n')) + break; } /* FALL THROUGH */ @@ -111,42 +135,10 @@ telrcv(void) state = TS_IAC; break; } - /* - * We now map \r\n ==> \r for pragmatic reasons. - * Many client implementations send \r\n when - * the user hits the CarriageReturn key. - * - * We USED to map \r\n ==> \n, since \r\n says - * that we want to be in column 1 of the next - * printable line, and \n is the standard - * unix way of saying that (\r is only good - * if CRMOD is set, which it normally is). - */ - if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) { - int nc = *netip; -#ifdef ENCRYPTION - if (decrypt_input) - nc = (*decrypt_input)(nc & 0xff); -#endif /* ENCRYPTION */ -#ifdef LINEMODE - /* - * If we are operating in linemode, - * convert to local end-of-line. - */ - if (linemode && (ncc > 0) && (('\n' == nc) || - ((0 == nc) && tty_iscrnl())) ) { - netip++; ncc--; - c = '\n'; - } else -#endif - { -#ifdef ENCRYPTION - if (decrypt_input) - (void)(*decrypt_input)(-1); -#endif /* ENCRYPTION */ - state = TS_CR; - } - } + + if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) + state = TS_CR; + *pfrontp++ = c; break; @@ -557,8 +549,10 @@ willoption(int option) #ifdef AUTHENTICATION case TELOPT_AUTHENTICATION: - func = auth_request; - changeok++; + if (auth_level >= 0) { + func = auth_request; + changeok++; + } break; #endif Index: src/libexec/telnetd/sys_term.c diff -u src/libexec/telnetd/sys_term.c:1.48.2.1 src/libexec/telnetd/sys_term.c:1.48.2.2 --- src/libexec/telnetd/sys_term.c:1.48.2.1 Fri Aug 16 19:12:46 2019 +++ src/libexec/telnetd/sys_term.c Mon Nov 18 19:44:57 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: sys_term.c,v 1.48.2.1 2019/08/16 19:12:46 martin Exp $ */ +/* $NetBSD: sys_term.c,v 1.48.2.2 2024/11/18 19:44:57 martin Exp $ */ /* * Copyright (c) 1989, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)sys_term.c 8.4+1 (Berkeley) 5/30/95"; #else -__RCSID("$NetBSD: sys_term.c,v 1.48.2.1 2019/08/16 19:12:46 martin Exp $"); +__RCSID("$NetBSD: sys_term.c,v 1.48.2.2 2024/11/18 19:44:57 martin Exp $"); #endif #endif /* not lint */ @@ -583,6 +583,10 @@ start_login(char *host, int autologin, c 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 @@ start_login(char *host, int autologin, c 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 Index: src/libexec/telnetd/telnetd.c diff -u src/libexec/telnetd/telnetd.c:1.55.28.2 src/libexec/telnetd/telnetd.c:1.55.28.3 --- src/libexec/telnetd/telnetd.c:1.55.28.2 Mon Aug 29 16:13:25 2022 +++ src/libexec/telnetd/telnetd.c Mon Nov 18 19:44:57 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: telnetd.c,v 1.55.28.2 2022/08/29 16:13:25 martin Exp $ */ +/* $NetBSD: telnetd.c,v 1.55.28.3 2024/11/18 19:44:57 martin Exp $ */ /* * Copyright (C) 1997 and 1998 WIDE Project. @@ -65,7 +65,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 19 #if 0 static char sccsid[] = "@(#)telnetd.c 8.4 (Berkeley) 5/30/95"; #else -__RCSID("$NetBSD: telnetd.c,v 1.55.28.2 2022/08/29 16:13:25 martin Exp $"); +__RCSID("$NetBSD: telnetd.c,v 1.55.28.3 2024/11/18 19:44:57 martin Exp $"); #endif #endif /* not lint */ @@ -242,7 +242,7 @@ main(int argc, char *argv[]) #ifdef ENCRYPTION case 'e': if (strcmp(optarg, "debug") == 0) { - encrypt_debug_mode = 1; + EncryptDebug(1); break; } usage(); @@ -400,6 +400,7 @@ main(int argc, char *argv[]) (void) dup2(ns, 0); (void) close(ns); (void) close(s); + freeaddrinfo(res); } else if (argc > 0) { usage(); /* NOT REACHED */ @@ -492,11 +493,13 @@ getterminaltype(char *name, size_t l) /* * 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