diff options
Diffstat (limited to 'src/appl/telnet')
24 files changed, 663 insertions, 495 deletions
diff --git a/src/appl/telnet/libtelnet/ChangeLog b/src/appl/telnet/libtelnet/ChangeLog index 67877b1..95906f3 100644 --- a/src/appl/telnet/libtelnet/ChangeLog +++ b/src/appl/telnet/libtelnet/ChangeLog @@ -1,3 +1,41 @@ +2003-04-01 Nalin Dahyabhai <nalin@redhat.com> + + * kerberos5.c (kerberos5_is): Check principal name length before + examining components. + +2002-03-29 Tom Yu <tlyu@mit.edu> + + * kerberos5.c, kerberos.c (Data): Don't overflow + buffer. [telnet/1073] [pullup and reindent from trunk] + +2001-02-21 Tom Yu <tlyu@mit.edu> + + * configure.in: Check for setenv, unsetenv, and getenv. Compile + setenv.c if at least of these is undefined. + + * setenv.c: Add conditionals for compilation of setenv, unsetenv, + and getenv such that they only get compiled if they don't already + exist. + +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * gettytab.c (nchktc): Don't overflow tcname if tty type name is too + long + * kerberos.c (kerberos4_status): Make sure "UserNameRequested" is + always properly terminated. + * kerberos5.c (kerberos5_is): If bad principal name is too long to fit + in "errbuf", don't print it. + (kerberos5_status): Make sure "UserNameRequested" is always properly + terminated. + * spx.c (spx_status): Ditto. + +2000-04-28 Nalin Dahyabhai <nalin@redhat.com> + + * kerberos5.c (kerberos5_is): Don't overflow buffer "errbuf". + * spx.c (spx_init, spx_send, spx_is): Don't overflow buffer + "targ_printable". + (spx_status): Don't overflow buffer "acl_file". + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/appl/telnet/libtelnet/configure.in b/src/appl/telnet/libtelnet/configure.in index 3bae866..9040a98 100644 --- a/src/appl/telnet/libtelnet/configure.in +++ b/src/appl/telnet/libtelnet/configure.in @@ -3,10 +3,14 @@ CONFIG_RULES AC_PROG_ARCHIVE AC_PROG_ARCHIVE_ADD AC_PROG_RANLIB -AC_REPLACE_FUNCS([strcasecmp strdup setenv setsid strerror strftime getopt herror parsetos]) -AC_CHECK_FUNCS(gettosbyname cgetent) +AC_REPLACE_FUNCS([strcasecmp strdup setsid strerror strftime getopt herror parsetos]) +AC_CHECK_FUNCS(setenv unsetenv getenv gettosbyname cgetent) AC_CHECK_HEADERS(stdlib.h string.h) LIBOBJS="$LIBOBJS getent.o" +if test $ac_cv_func_setenv = no || test $ac_cv_func_unsetenv = no \ + || test $ac_cv_func_getenv = no; then + LIBOBJS="$LIBOBJS setenv.o" +fi AC_CONST if test "$KRB4_LIB" = ''; then AC_MSG_RESULT(No Kerberos 4 authentication) diff --git a/src/appl/telnet/libtelnet/gettytab.c b/src/appl/telnet/libtelnet/gettytab.c index f6ffb7c..aaad43a 100644 --- a/src/appl/telnet/libtelnet/gettytab.c +++ b/src/appl/telnet/libtelnet/gettytab.c @@ -98,9 +98,10 @@ nchktc() /* p now points to beginning of last field */ if (p[0] != 't' || p[1] != 'c') return(1); - strcpy(tcname,p+3); + strncpy(tcname, p + 3, sizeof(tcname) - 1); + tcname[sizeof(tcname) - 1] = '\0'; q = tcname; - while (q && *q != ':') + while (*q && *q != ':') q++; *q = 0; if (++hopcount > MAXHOP) { diff --git a/src/appl/telnet/libtelnet/kerberos.c b/src/appl/telnet/libtelnet/kerberos.c index 734466e..0fda99b 100644 --- a/src/appl/telnet/libtelnet/kerberos.c +++ b/src/appl/telnet/libtelnet/kerberos.c @@ -141,6 +141,7 @@ Data(ap, type, d, c) { unsigned char *p = str_data + 4; unsigned char *cd = (unsigned char *)d; + size_t spaceleft = sizeof(str_data) - 4; if (c == -1) c = strlen((char *)cd); @@ -156,9 +157,16 @@ Data(ap, type, d, c) *p++ = ap->type; *p++ = ap->way; *p++ = type; + spaceleft -= 3; while (c-- > 0) { - if ((*p++ = *cd++) == IAC) - *p++ = IAC; + if ((*p++ = *cd++) == IAC) { + *p++ = IAC; + spaceleft--; + } + if ((--spaceleft < 4) && c) { + errno = ENOMEM; + return -1; + } } *p++ = IAC; *p++ = SE; @@ -602,7 +610,9 @@ kerberos4_status(ap, name, level) return(level); if (UserNameRequested && !kuserok(&adat, UserNameRequested)) { - strcpy(name, UserNameRequested); + /* the name buffer comes from telnetd/telnetd{-ktd}.c */ + strncpy(name, UserNameRequested, 255); + name[255] = '\0'; return(AUTH_VALID); } else return(AUTH_USER); diff --git a/src/appl/telnet/libtelnet/kerberos5.c b/src/appl/telnet/libtelnet/kerberos5.c index 6a62f36..b9bbae8 100644 --- a/src/appl/telnet/libtelnet/kerberos5.c +++ b/src/appl/telnet/libtelnet/kerberos5.c @@ -95,7 +95,7 @@ void kerberos5_forward(); #endif /* FORWARD */ -static unsigned char str_data[2048] = { IAC, SB, TELOPT_AUTHENTICATION, 0, +static unsigned char str_data[8192] = {IAC, SB, TELOPT_AUTHENTICATION, 0, AUTHTYPE_KERBEROS_V5, }; /*static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, };*/ @@ -136,6 +136,7 @@ Data(ap, type, d, c) { unsigned char *p = str_data + 4; unsigned char *cd = (unsigned char *)d; + size_t spaceleft = sizeof(str_data) - 4; if (c == -1) c = strlen((char *)cd); @@ -151,9 +152,16 @@ Data(ap, type, d, c) *p++ = ap->type; *p++ = ap->way; *p++ = type; + spaceleft -= 3; while (c-- > 0) { - if ((*p++ = *cd++) == IAC) - *p++ = IAC; + if ((*p++ = *cd++) == IAC) { + *p++ = IAC; + spaceleft--; + } + if ((--spaceleft < 4) && c) { + errno = ENOMEM; + return -1; + } } *p++ = IAC; *p++ = SE; @@ -423,7 +431,8 @@ kerberos5_is(ap, data, cnt) NULL, keytabid, NULL, &ticket); if (r) { (void) strcpy(errbuf, "krb5_rd_req failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); goto errout; } @@ -432,6 +441,10 @@ kerberos5_is(ap, data, cnt) * first component of a service name especially since * the default is of length 4. */ + if (krb5_princ_size(telnet_context,ticket->server) < 1) { + (void) strcpy(errbuf, "malformed service name"); + goto errout; + } if (krb5_princ_component(telnet_context,ticket->server,0)->length < 256) { char princ[256]; strncpy(princ, @@ -440,8 +453,12 @@ kerberos5_is(ap, data, cnt) princ[krb5_princ_component(telnet_context, ticket->server,0)->length] = '\0'; if (strcmp("host", princ)) { - (void) sprintf(errbuf, "incorrect service name: \"%s\" != \"%s\"", - princ, "host"); + if(strlen(princ) < sizeof(errbuf) - 39) { + (void) sprintf(errbuf, "incorrect service name: \"%s\" != \"host\"", + princ); + } else { + (void) sprintf(errbuf, "incorrect service name: principal != \"host\""); + } goto errout; } } else { @@ -455,7 +472,8 @@ kerberos5_is(ap, data, cnt) if (r) { (void) strcpy(errbuf, "krb5_auth_con_getauthenticator failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); goto errout; } if ((ap->way & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON && @@ -476,7 +494,8 @@ kerberos5_is(ap, data, cnt) &key); if (r) { (void) strcpy(errbuf, "krb5_auth_con_getkey failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); goto errout; } r = krb5_verify_checksum(telnet_context, @@ -495,7 +514,8 @@ kerberos5_is(ap, data, cnt) if (r) { (void) strcpy(errbuf, "checksum verification failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); goto errout; } krb5_free_keyblock(telnet_context, key); @@ -506,7 +526,8 @@ kerberos5_is(ap, data, cnt) if ((r = krb5_mk_rep(telnet_context, auth_context, &outbuf))) { (void) strcpy(errbuf, "Make reply failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); goto errout; } @@ -560,7 +581,8 @@ kerberos5_is(ap, data, cnt) char errbuf[128]; (void) strcpy(errbuf, "Read forwarded creds failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); Data(ap, KRB_FORWARD_REJECT, errbuf, -1); if (auth_debug_mode) printf( @@ -586,7 +608,8 @@ kerberos5_is(ap, data, cnt) char eerrbuf[329]; strcpy(eerrbuf, "telnetd: "); - strcat(eerrbuf, errbuf); + eerrbuf[sizeof(eerrbuf) - 1] = '\0'; + strncat(eerrbuf, errbuf, sizeof(eerrbuf) - 1 - strlen(eerrbuf)); Data(ap, KRB_REJECT, eerrbuf, -1); } if (auth_debug_mode) @@ -706,7 +729,9 @@ kerberos5_status(ap, name, level) krb5_kuserok(telnet_context, ticket->enc_part2->client, UserNameRequested)) { - strcpy(name, UserNameRequested); + /* the name buffer comes from telnetd/telnetd{-ktd}.c */ + strncpy(name, UserNameRequested, 255); + name[255] = '\0'; return(AUTH_VALID); } else return(AUTH_USER); diff --git a/src/appl/telnet/libtelnet/setenv.c b/src/appl/telnet/libtelnet/setenv.c index 70695a3..bc4f22d 100644 --- a/src/appl/telnet/libtelnet/setenv.c +++ b/src/appl/telnet/libtelnet/setenv.c @@ -52,6 +52,7 @@ static char *__findenv __P((const char *, int *)); * Set the value of the environmental variable "name" to be * "value". If rewrite is set, replace any current value. */ +#ifndef HAVE_SETENV setenv(name, value, rewrite) register const char *name; register const char *value; @@ -102,11 +103,13 @@ setenv(name, value, rewrite) for (*c++ = '='; *c++ = *value++;); return (0); } +#endif /* * unsetenv(name) -- * Delete environmental variable "name". */ +#ifndef HAVE_UNSETENV void unsetenv(name) const char *name; @@ -120,11 +123,13 @@ unsetenv(name) if (!(*p = *(p + 1))) break; } +#endif /* * getenv -- * Returns ptr to value associated with name, if any, else NULL. */ +#ifndef HAVE_GETENV char * getenv(name) const char *name; @@ -133,6 +138,7 @@ getenv(name) return (__findenv(name, &offset)); } +#endif /* * __findenv -- diff --git a/src/appl/telnet/libtelnet/spx.c b/src/appl/telnet/libtelnet/spx.c index f23490f..7285d0d 100644 --- a/src/appl/telnet/libtelnet/spx.c +++ b/src/appl/telnet/libtelnet/spx.c @@ -173,7 +173,8 @@ spx_init(ap, server) str_data[3] = TELQUAL_REPLY; gethostname(lhostname, sizeof(lhostname)); strcpy(targ_printable, "SERVICE:rcmd@"); - strcat(targ_printable, lhostname); + strncat(targ_printable, lhostname, sizeof(targ_printable) - 1 - 13); + targ_printable[sizeof(targ_printable) - 1] = '\0'; input_name_buffer.length = strlen(targ_printable); input_name_buffer.value = targ_printable; major_status = gss_import_name(&status, @@ -216,7 +217,8 @@ spx_send(ap) printf("[ Trying SPX ... ]\n"); strcpy(targ_printable, "SERVICE:rcmd@"); - strcat(targ_printable, RemoteHostName); + strncat(targ_printable, RemoteHostName, sizeof(targ_printable) - 1 - 13); + targ_printable[sizeof(targ_printable) - 1] = '\0'; input_name_buffer.length = strlen(targ_printable); input_name_buffer.value = targ_printable; @@ -324,7 +326,8 @@ spx_is(ap, data, cnt) gethostname(lhostname, sizeof(lhostname)); strcpy(targ_printable, "SERVICE:rcmd@"); - strcat(targ_printable, lhostname); + strncat(targ_printable, lhostname, sizeof(targ_printable) - 1 - 13); + targ_printable[sizeof(targ_printable) - 1] = '\0'; input_name_buffer.length = strlen(targ_printable); input_name_buffer.value = targ_printable; @@ -479,7 +482,7 @@ spx_status(ap, name, level) gss_buffer_desc fullname_buffer, acl_file_buffer; gss_OID fullname_type; - char acl_file[160], fullname[160]; + char acl_file[MAXPATHLEN], fullname[160]; int major_status, status = 0; struct passwd *pwd; @@ -494,8 +497,9 @@ spx_status(ap, name, level) return(AUTH_USER); /* not authenticated */ } - strcpy(acl_file, pwd->pw_dir); - strcat(acl_file, "/.sphinx"); + acl_file[sizeof(acl_file) - 1] = '\0'; + strncpy(acl_file, pwd->pw_dir, sizeof(acl_file) - 1); + strncat(acl_file, "/.sphinx", sizeof(acl_file) - 1 - strlen(acl_file)); acl_file_buffer.value = acl_file; acl_file_buffer.length = strlen(acl_file); @@ -511,7 +515,9 @@ spx_status(ap, name, level) &acl_file_buffer); if (major_status == GSS_S_COMPLETE) { - strcpy(name, UserNameRequested); + /* the name buffer comes from telnetd/telnetd{-ktd}.c */ + strncpy(name, UserNameRequested, 255); + name[255] = '\0'; return(AUTH_VALID); } else { return(AUTH_USER); diff --git a/src/appl/telnet/telnet/ChangeLog b/src/appl/telnet/telnet/ChangeLog index e3cfb63..fb7cc9394 100644 --- a/src/appl/telnet/telnet/ChangeLog +++ b/src/appl/telnet/telnet/ChangeLog @@ -1,3 +1,18 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * commands.c (makeargv): Don't overflow buffer "saveline". + (tn): Don't overflow buffer "_hostname". + (cmdrc): Don't overflow buffer "m1save". + * externs.h: Include the size of "tline", so that we can check for + overflows elsewhere. + * main.c(main, tn370): Don't overflow buffer "tline". + * utilities.c (SetNetTrace): Don't overflow buffer "NetTraceFile". + +2000-04-28 Nalin Dahyabhai <nalin@redhat.com> + + * commands.c (cmdrc): Don't overflow buffer "rcbuf". + * tn3270.c (settranscom): Don't overflow buffer "transcom". + 2000-02-24 Ezra Peisach <epeisach@mit.edu> * configure.in: Remove dependency on libdes425 when krb4 support diff --git a/src/appl/telnet/telnet/commands.c b/src/appl/telnet/telnet/commands.c index 2c80b0b..8ffba2e 100644 --- a/src/appl/telnet/telnet/commands.c +++ b/src/appl/telnet/telnet/commands.c @@ -138,7 +138,9 @@ makeargv() margc = 0; cp = line; if (*cp == '!') { /* Special case shell escape */ - strcpy(saveline, line); /* save for shell command */ + strncpy(saveline, line, sizeof(saveline) - 1); + /* save for shell command */ + saveline[sizeof(saveline) - 1] = '\0'; *argp++ = "!"; /* No room in string to get this */ margc++; cp++; @@ -2450,7 +2452,8 @@ tn(argc, argv) if (temp & 0xffffffff != INADDR_NONE) { sin.sin_addr.s_addr = temp; sin.sin_family = AF_INET; - (void) strcpy(_hostname, hostp); + (void) strncpy(_hostname, hostp, sizeof(_hostname) - 1); + _hostname[sizeof(_hostname) - 1] = '\0'; hostname = _hostname; } else { host = gethostbyname(hostp); @@ -2855,16 +2858,18 @@ cmdrc(m1, m2) if (skiprc) return; - strcpy(m1save, m1); + strncpy(m1save, m1, sizeof(m1save) - 1); + m1save[sizeof(m1save) - 1] = '\0'; m1 = m1save; if (rcname == 0) { rcname = getenv("HOME"); if (rcname) - strcpy(rcbuf, rcname); + strncpy(rcbuf, rcname, sizeof(rcbuf) - 1); else rcbuf[0] = '\0'; - strcat(rcbuf, "/.telnetrc"); + rcbuf[sizeof(rcbuf) - 1] = '\0'; + strncat(rcbuf, "/.telnetrc", sizeof(rcbuf) - 1 - strlen(rcbuf)); rcname = rcbuf; } diff --git a/src/appl/telnet/telnet/externs.h b/src/appl/telnet/telnet/externs.h index e993986..f35cded 100644 --- a/src/appl/telnet/telnet/externs.h +++ b/src/appl/telnet/telnet/externs.h @@ -486,7 +486,7 @@ extern char *Ibackp, /* Oldest byte of 3270 data */ Ibuf[], /* 3270 buffer */ *Ifrontp, /* Where next 3270 byte goes */ - tline[], + tline[200], *transcom; /* Transparent command */ extern int diff --git a/src/appl/telnet/telnet/main.c b/src/appl/telnet/telnet/main.c index da98ae6..7696857 100644 --- a/src/appl/telnet/telnet/main.c +++ b/src/appl/telnet/telnet/main.c @@ -274,7 +274,8 @@ main(argc, argv) case 't': #if defined(TN3270) && defined(unix) transcom = tline; - (void)strcpy(transcom, optarg); + (void)strncpy(transcom, optarg, sizeof(tline) - 1); + tline[sizeof(tline) - 1] = '\0'; #else fprintf(stderr, "%s: Warning: -t ignored, no TN3270 support.\n", diff --git a/src/appl/telnet/telnet/tn3270.c b/src/appl/telnet/telnet/tn3270.c index 77aedaf..c46ae7e 100644 --- a/src/appl/telnet/telnet/tn3270.c +++ b/src/appl/telnet/telnet/tn3270.c @@ -397,10 +397,11 @@ settranscom(argc, argv) return 1; } transcom = tline; - (void) strcpy(transcom, argv[1]); + (void) strncpy(transcom, argv[1], sizeof(tline) - 1); + tline[sizeof(tline) - 1] = '\0'; for (i = 2; i < argc; ++i) { - (void) strcat(transcom, " "); - (void) strcat(transcom, argv[i]); + (void) strncat(transcom, " ", sizeof(tline) - 1 - (transcom - tline)); + (void) strncat(transcom, argv[i], sizeof(tline) - 1 - (transcom - tline)); } return 1; } diff --git a/src/appl/telnet/telnet/utilities.c b/src/appl/telnet/telnet/utilities.c index 19f503b..82ad841 100644 --- a/src/appl/telnet/telnet/utilities.c +++ b/src/appl/telnet/telnet/utilities.c @@ -113,13 +113,15 @@ SetNetTrace(file) if (file && (strcmp(file, "-") != 0)) { NetTrace = fopen(file, "w"); if (NetTrace) { - strcpy((char *)NetTraceFile, file); + strncpy((char *)NetTraceFile, file, sizeof(NetTraceFile) - 1); + NetTraceFile[sizeof(NetTraceFile) - 1] = '\0'; return; } fprintf(stderr, "Cannot open %s.\n", file); } NetTrace = stdout; - strcpy((char *)NetTraceFile, "(standard output)"); + strncpy((char *)NetTraceFile, "(standard output)", sizeof(NetTraceFile) - 1); + NetTraceFile[sizeof(NetTraceFile) - 1] = '\0'; } void diff --git a/src/appl/telnet/telnetd/ChangeLog b/src/appl/telnet/telnetd/ChangeLog index 040a9af..5ab914a 100644 --- a/src/appl/telnet/telnetd/ChangeLog +++ b/src/appl/telnet/telnetd/ChangeLog @@ -1,3 +1,70 @@ +2002-01-18 Tom Yu <tlyu@mit.edu> + + * ext.h: Make stdarg prototypes unconditional, to avoid annoying + mostly-ANSI compilers that don't define __STDC__. + +2001-10-15 Ken Raeburn <raeburn@mit.edu> + + * telnetd.c (valid_opts): Note that 'w' takes a parameter. + +2001-08-02 Tom Yu <tlyu@mit.edu> + + * authenc.c (net_write): Rewrite in terms of netwrite(). + + * configure.in: Check for vsnprintf(). + + * ext.h: New prototypes for netprintf, netprintf_urg, + netprintf_noflush, netwrite, netputs. + + * slc.c: Fix to use new NETOBUF-handling functions. + + * state.c: Fix to use new NETOBUF-handling functions. + + * telnetd.c: Fix to use new NETOBUF-handling functions. + + * termstat.c: Fix to use new NETOBUF-handling functions. + + * utility.c: General rework to be more paranoid about + bounds-checking of NETOBUF and NFRONTP. Abstract away + interactions with NETOBUF to eliminate explicit references to + NFRONTP in many places. + (netwrite): New function; copies a buffer to the + NETOBUF "ring buffer", checking bounds and calling netflush() if + needed. + (netputs): New function; calls netwrite() with a nul-terminated + string. + (netprintf, netprintf_ext): New function; wrap sprintf() with + bounds checking for use with NETOBUF. + (netprintf_urg): New function; like netprintf() except sets neturg + to point at last char written. + (netprintf_noflush): New function; like netprintf() except + silently fails if NETOBUF is full. + (ttloop, printoption, printsub, printdata): Fix to use new + NETOBUF-handling functions. + +2001-01-25 Tom Yu <tlyu@mit.edu> + + * state.c (envvarok): Disallow LC_* and NLSPATH. + +2000-06-19 Tom Yu <tlyu@mit.edu> + + * telnetd.c (doit): Change test for "no authentication" as per + Jeffrey Altman's patch. + +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * sys_term.c (start_login, Solaris): forcefully terminate "termbuf" + in case the "TERM" environment variable isn't. + * telnet-ktd.c (getterminaltype): Don't overflow buffers "first" and + "netobuf". + (recv_ayt): Forcibly terminate buffer "netobuf". + +2000-03-20 Ken Raeburn <raeburn@mit.edu> + Jeffrey Altman <jaltman@watsun.cc.columbia.edu> + + * state.c (telrcv): Fix off-by-one error dealing with full + buffer. + 2000-02-24 Ezra Peisach <epeisach@mit.edu> * configure.in: Remove dependency on libdes425 when krb4 support diff --git a/src/appl/telnet/telnetd/authenc.c b/src/appl/telnet/telnetd/authenc.c index 5736698..4488954 100644 --- a/src/appl/telnet/telnetd/authenc.c +++ b/src/appl/telnet/telnetd/authenc.c @@ -37,20 +37,17 @@ #include "telnetd.h" #include <libtelnet/misc.h> - int +int net_write(str, len) unsigned char *str; int len; { - if (nfrontp + len < netobuf + BUFSIZ) { - memcpy((void *)nfrontp, (void *)str, len); - nfrontp += len; - return(len); - } - return(0); + if (len < 0) + return 0; + return netwrite(str, len); } - void +void net_encrypt() { #ifdef ENCRYPTION @@ -87,7 +84,3 @@ telnet_gets(prompt, result, length, echo) return((char *)0); } #endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ - - - - diff --git a/src/appl/telnet/telnetd/configure.in b/src/appl/telnet/telnetd/configure.in index e11b270..2dc6099 100644 --- a/src/appl/telnet/telnetd/configure.in +++ b/src/appl/telnet/telnetd/configure.in @@ -23,7 +23,7 @@ fi fi AC_HEADER_TIME AC_CHECK_HEADERS(string.h arpa/nameser.h utmp.h sys/time.h sys/tty.h sac.h sys/ptyvar.h sys/filio.h sys/stream.h sys/utsname.h) -AC_CHECK_FUNCS(gettosbyname) +AC_CHECK_FUNCS(gettosbyname vsnprintf) dnl Make our operating system-specific security checks and definitions for dnl login. dnl diff --git a/src/appl/telnet/telnetd/ext.h b/src/appl/telnet/telnetd/ext.h index 2ff53e3..dc9fe5a 100644 --- a/src/appl/telnet/telnetd/ext.h +++ b/src/appl/telnet/telnetd/ext.h @@ -187,8 +187,13 @@ extern void tty_setsofttab P((int)), tty_tspeed P((int)), willoption P((int)), - wontoption P((int)), - writenet P((unsigned char *, int)); + wontoption P((int)); + +extern void netprintf(const char *, ...); +extern void netprintf_urg(const char *fmt, ...); +extern void netprintf_noflush(const char *fmt, ...); +extern int netwrite(const char *, size_t); +extern void netputs(const char *); #ifdef ENCRYPTION extern char *nclearto; diff --git a/src/appl/telnet/telnetd/slc.c b/src/appl/telnet/telnetd/slc.c index 1c68b95..613674b 100644 --- a/src/appl/telnet/telnetd/slc.c +++ b/src/appl/telnet/telnetd/slc.c @@ -198,7 +198,7 @@ end_slc(bufp) (void) sprintf((char *)slcptr, "%c%c", IAC, SE); slcptr += 2; len = slcptr - slcbuf; - writenet(slcbuf, len); + netwrite(slcbuf, len); netflush(); /* force it out immediately */ DIAG(TD_OPTIONS, printsub('>', slcbuf+2, len-2);); } diff --git a/src/appl/telnet/telnetd/state.c b/src/appl/telnet/telnetd/state.c index 0f3b161..d783ed6 100644 --- a/src/appl/telnet/telnetd/state.c +++ b/src/appl/telnet/telnetd/state.c @@ -86,7 +86,7 @@ static void sb_auth_complete() if (!auth_negotiated) { static char *error = "An environment option was sent before authentication negotiation completed.\r\nThis may create a security hazard. Connection dropped.\r\n"; - writenet(error, strlen(error)); + netputs(error); netflush(); exit(1); } @@ -102,7 +102,7 @@ telrcv() #endif while (ncc > 0) { - if ((&ptyobuf[BUFSIZ] - pfrontp) < 2) + if ((&ptyobuf[BUFSIZ] - pfrontp) < 1) break; c = *netip++ & 0377, ncc--; #ifdef ENCRYPTION @@ -209,9 +209,7 @@ gotiac: switch (c) { } netclear(); /* clear buffer back */ - *nfrontp++ = IAC; - *nfrontp++ = DM; - neturg = nfrontp-1; /* off by one XXX */ + netprintf_urg("%c%c", IAC, DM); DIAG(TD_OPTIONS, printoption("td: send IAC", DM)); break; @@ -381,9 +379,12 @@ gotiac: switch (c) { pfrontp = opfrontp; pfrontp += term_input(xptyobuf, pfrontp, n, BUFSIZ+NETSLOP, xbuf2, &oc, BUFSIZ); - for (cp = xbuf2; oc > 0; --oc) - if ((*nfrontp++ = *cp++) == IAC) - *nfrontp++ = IAC; + for (cp = xbuf2; oc > 0; --oc) { + if (*cp == IAC) + netprintf("%c%c", *cp++, IAC); + else + netprintf("%c", *cp++); + } } #endif /* defined(CRAY2) && defined(UNICOS5) */ } /* end of telrcv */ @@ -463,8 +464,7 @@ send_do(option, init) set_his_want_state_will(option); do_dont_resp[option]++; } - (void) sprintf(nfrontp, (char *)doopt, option); - nfrontp += sizeof (dont) - 2; + netprintf((char *)doopt, option); DIAG(TD_OPTIONS, printoption("td: send do", option)); } @@ -683,8 +683,7 @@ send_dont(option, init) set_his_want_state_wont(option); do_dont_resp[option]++; } - (void) sprintf(nfrontp, (char *)dont, option); - nfrontp += sizeof (doopt) - 2; + netprintf((char *)dont, option); DIAG(TD_OPTIONS, printoption("td: send dont", option)); } @@ -833,8 +832,7 @@ send_will(option, init) set_my_want_state_will(option); will_wont_resp[option]++; } - (void) sprintf(nfrontp, (char *)will, option); - nfrontp += sizeof (doopt) - 2; + netprintf((char *)will, option); DIAG(TD_OPTIONS, printoption("td: send will", option)); } @@ -993,8 +991,7 @@ send_wont(option, init) set_my_want_state_wont(option); will_wont_resp[option]++; } - (void) sprintf(nfrontp, (char *)wont, option); - nfrontp += sizeof (wont) - 2; + netprintf((char *)wont, option); DIAG(TD_OPTIONS, printoption("td: send wont", option)); } @@ -1393,10 +1390,8 @@ suboption() env_ovar_wrong: env_ovar = OLD_ENV_VALUE; env_ovalue = OLD_ENV_VAR; - DIAG(TD_OPTIONS, {sprintf(nfrontp, - "ENVIRON VALUE and VAR are reversed!\r\n"); - nfrontp += strlen(nfrontp);}); - + DIAG(TD_OPTIONS, + netputs("ENVIRON VALUE and VAR are reversed!\r\n")); } } SB_RESTORE(); @@ -1633,7 +1628,7 @@ send_status() ADD(IAC); ADD(SE); - writenet(statusbuf, ncp - statusbuf); + netwrite(statusbuf, ncp - statusbuf); netflush(); /* Send it on its way */ DIAG(TD_OPTIONS, @@ -1663,6 +1658,8 @@ static int envvarok(varp) strcmp(varp, "KRB_REALMS") && /* cns v4 */ strcmp(varp, "LIBPATH") && /* AIX */ strcmp(varp, "RESOLV_HOST_CONF") && /* linux */ + strcmp(varp, "NLSPATH") && /* locale stuff */ + strncmp(varp, "LC_", strlen("LC_")) && /* locale stuff */ strcmp(varp, "IFS")) { return 1; } else { diff --git a/src/appl/telnet/telnetd/sys_term.c b/src/appl/telnet/telnetd/sys_term.c index ee8d53d..b79209d 100644 --- a/src/appl/telnet/telnetd/sys_term.c +++ b/src/appl/telnet/telnetd/sys_term.c @@ -1257,6 +1257,7 @@ start_login(host, autologin, name) } else { strcpy(termbuf, "TERM="); strncat(termbuf, term, sizeof(termbuf) - 6); + termbuf[sizeof(termbuf) - 1] = '\0'; term = termbuf; } argv = addarg(argv, term); diff --git a/src/appl/telnet/telnetd/telnetd-ktd.c b/src/appl/telnet/telnetd/telnetd-ktd.c index 9ec608f..5936e3b 100644 --- a/src/appl/telnet/telnetd/telnetd-ktd.c +++ b/src/appl/telnet/telnetd/telnetd-ktd.c @@ -360,7 +360,7 @@ main(argc, argv) } (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); - if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) { + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { perror("bind"); exit(1); } @@ -368,7 +368,7 @@ main(argc, argv) perror("listen"); exit(1); } - foo = sizeof sin; + foo = sizeof(sin); ns = accept(s, (struct sockaddr *)&sin, &foo); if (ns < 0) { perror("accept"); @@ -548,25 +548,33 @@ getterminaltype(name) if (his_state_is_will(TELOPT_TSPEED)) { static char sbbuf[] = { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; - memcpy(nfrontp, sbbuf, sizeof sbbuf); - nfrontp += sizeof sbbuf; + if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) { + memcpy(nfrontp, sbbuf, sizeof(sbbuf)); + nfrontp += sizeof(sbbuf); + } } if (his_state_is_will(TELOPT_XDISPLOC)) { static char sbbuf[] = { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE }; - memcpy(nfrontp, sbbuf, sizeof sbbuf); - nfrontp += sizeof sbbuf; + if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) { + memcpy(nfrontp, sbbuf, sizeof(sbbuf)); + nfrontp += sizeof(sbbuf); + } } if (his_state_is_will(TELOPT_ENVIRON)) { static char sbbuf[] = { IAC, SB, TELOPT_ENVIRON, TELQUAL_SEND, IAC, SE }; - memcpy(nfrontp, sbbuf, sizeof sbbuf); - nfrontp += sizeof sbbuf; + if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) { + memcpy(nfrontp, sbbuf, sizeof(sbbuf)); + nfrontp += sizeof(sbbuf); + } } if (his_state_is_will(TELOPT_TTYPE)) { - memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); - nfrontp += sizeof ttytype_sbbuf; + if(nfrontp - netobuf + sizeof(ttytype_sbbuf) < sizeof(netobuf)) { + memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf)); + nfrontp += sizeof(ttytype_sbbuf); + } } if (his_state_is_will(TELOPT_TSPEED)) { while (sequenceIs(tspeedsubopt, baseline)) @@ -591,12 +599,14 @@ getterminaltype(name) * we have to just go with what we (might) have already gotten. */ if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) { - (void) strncpy(first, terminaltype, sizeof(first)); + (void) strncpy(first, terminaltype, sizeof(first) - 1); + first[sizeof(first) - 1] = '\0'; for(;;) { /* * Save the unknown name, and request the next name. */ - (void) strncpy(last, terminaltype, sizeof(last)); + (void) strncpy(last, terminaltype, sizeof(last) - 1); + last[sizeof(last) - 1] = '\0'; _gettermname(); if (terminaltypeok(terminaltype)) break; @@ -615,7 +625,8 @@ getterminaltype(name) */ _gettermname(); if (strncmp(first, terminaltype, sizeof(first)) != 0) - (void) strncpy(terminaltype, first, sizeof(first)); + (void) strncpy(terminaltype, first, sizeof(terminaltype) - 1); + terminaltype[sizeof(terminaltype) - 1] = '\0'; break; } } @@ -635,8 +646,8 @@ _gettermname() if (his_state_is_wont(TELOPT_TTYPE)) return; settimer(baseline); - memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); - nfrontp += sizeof ttytype_sbbuf; + memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf)); + nfrontp += sizeof(ttytype_sbbuf); while (sequenceIs(ttypesubopt, baseline)) ttloop(); } @@ -922,7 +933,7 @@ telnet(f, p, host) #if defined(SO_OOBINLINE) (void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE, - (char *)&on, sizeof on); + (char *)&on, sizeof(on)); #endif /* defined(SO_OOBINLINE) */ #ifdef SIGTSTP @@ -989,8 +1000,10 @@ telnet(f, p, host) HE = getstr("he", &cp); HN = getstr("hn", &cp); IM = getstr("im", &cp); - if (HN && *HN) - (void) strcpy(host_name, HN); + if (HN && *HN) { + (void) strncpy(host_name, HN, sizeof(host_name) - 1); + host_name[sizeof(host_name) - 1] = '\0'; + } if (IM == 0) IM = ""; } else { @@ -1426,8 +1439,10 @@ recv_ayt() return; } #endif - (void) strcpy(nfrontp, "\r\n[Yes]\r\n"); + (void) strncpy(nfrontp, "\r\n[Yes]\r\n", + sizeof(netobuf) - 1 - (nfrontp - netobuf)); nfrontp += 9; + *nfrontp = '\0'; } void diff --git a/src/appl/telnet/telnetd/telnetd.c b/src/appl/telnet/telnetd/telnetd.c index 7267469..5588d1a 100644 --- a/src/appl/telnet/telnetd/telnetd.c +++ b/src/appl/telnet/telnetd/telnetd.c @@ -153,7 +153,7 @@ extern void usage P((void)); */ char valid_opts[] = { 'd', ':', 'h', 'k', 'L', ':', 'n', 'S', ':', 'U', - 'w', + 'w', ':', #ifdef AUTHENTICATION 'a', ':', 'X', ':', #endif @@ -522,7 +522,7 @@ main(argc, argv) } (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); - if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) { + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { perror("bind"); exit(1); } @@ -530,7 +530,7 @@ main(argc, argv) perror("listen"); exit(1); } - foo = sizeof sin; + foo = sizeof(sin); ns = accept(s, (struct sockaddr *)&sin, &foo); if (ns < 0) { perror("accept"); @@ -693,7 +693,7 @@ static void encrypt_failure() char *error_message = "Encryption was not successfully negotiated. Goodbye.\r\n\r\n"; - writenet(error_message, strlen(error_message)); + netputs(error_message); netflush(); exit(1); } @@ -780,36 +780,26 @@ getterminaltype(name) if (his_state_is_will(TELOPT_TSPEED)) { static unsigned char sb[] = { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; - - memcpy(nfrontp, sb, sizeof sb); - nfrontp += sizeof sb; + netwrite(sb, sizeof(sb)); } if (his_state_is_will(TELOPT_XDISPLOC)) { static unsigned char sb[] = { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE }; - - memcpy(nfrontp, sb, sizeof sb); - nfrontp += sizeof sb; + netwrite(sb, sizeof(sb)); } if (his_state_is_will(TELOPT_NEW_ENVIRON)) { static unsigned char sb[] = { IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE }; - - memcpy(nfrontp, sb, sizeof sb); - nfrontp += sizeof sb; + netwrite(sb, sizeof(sb)); } else if (his_state_is_will(TELOPT_OLD_ENVIRON)) { static unsigned char sb[] = { IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE }; - - memcpy(nfrontp, sb, sizeof sb); - nfrontp += sizeof sb; + netwrite(sb, sizeof(sb)); } - if (his_state_is_will(TELOPT_TTYPE)) { + if (his_state_is_will(TELOPT_TTYPE)) + netwrite(ttytype_sbbuf, sizeof(ttytype_sbbuf)); - memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); - nfrontp += sizeof ttytype_sbbuf; - } if (his_state_is_will(TELOPT_TSPEED)) { while (sequenceIs(tspeedsubopt, baseline)) ttloop(); @@ -886,8 +876,7 @@ _gettermname() if (his_state_is_wont(TELOPT_TTYPE)) return; settimer(baseline); - memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); - nfrontp += sizeof ttytype_sbbuf; + netwrite(ttytype_sbbuf, sizeof(ttytype_sbbuf)); while (sequenceIs(ttypesubopt, baseline)) ttloop(); } @@ -1009,7 +998,7 @@ pty_init(); setenv("TERM", *terminaltype ? terminaltype : "network", 1); #if defined (AUTHENTICATION) - if (user_name[0] == '\0') { + if (level < 0 && auth_level > 0) { fatal (net, "No authentication provided"); exit (-1); } @@ -1159,9 +1148,7 @@ telnet(f, p, host) * mode, which we do not want. */ if (his_want_state_is_will(TELOPT_ECHO)) { - DIAG(TD_OPTIONS, - {sprintf(nfrontp, "td: simulating recv\r\n"); - nfrontp += strlen(nfrontp);}); + DIAG(TD_OPTIONS, netputs("td: simulating recv\r\n")); willoption(TELOPT_ECHO); } @@ -1205,7 +1192,7 @@ telnet(f, p, host) #if defined(SO_OOBINLINE) (void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE, - (char *)&on, sizeof on); + (char *)&on, sizeof(on)); #endif /* defined(SO_OOBINLINE) */ #ifdef SIGTSTP @@ -1266,7 +1253,8 @@ telnet(f, p, host) HN = getstr("hn", &cp); IM = getstr("im", &cp); if (HN && *HN) - (void) strcpy(host_name, HN); + (void) strncpy(host_name, HN, sizeof(host_name) - 1); + host_name[sizeof(host_name) - 1] = '\0'; if (IM == 0) IM = ""; } else { @@ -1289,9 +1277,7 @@ telnet(f, p, host) localstat(); #endif /* LINEMODE */ - DIAG(TD_REPORT, - {sprintf(nfrontp, "td: Entering processing loop\r\n"); - nfrontp += strlen(nfrontp);}); + DIAG(TD_REPORT, netputs("td: Entering processing loop\r\n")); #ifdef convex startslave(host); @@ -1416,8 +1402,7 @@ telnet(f, p, host) netip = netibuf; } DIAG((TD_REPORT | TD_NETDATA), - {sprintf(nfrontp, "td: netread %d chars\r\n", ncc); - nfrontp += strlen(nfrontp);}); + netprintf("td: netread %d chars\r\n", ncc)); DIAG(TD_NETDATA, printdata("nd", netip, ncc)); } @@ -1464,9 +1449,7 @@ telnet(f, p, host) * royally if we send them urgent * mode data. */ - *nfrontp++ = IAC; - *nfrontp++ = DM; - neturg = nfrontp-1; /* off by one XXX */ + netprintf_urg("%c%c", IAC, DM); #endif } if (his_state_is_will(TELOPT_LFLOW) && @@ -1476,13 +1459,11 @@ telnet(f, p, host) ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0; if (newflow != flowmode) { flowmode = newflow; - (void) sprintf(nfrontp, - "%c%c%c%c%c%c", + netprintf("%c%c%c%c%c%c", IAC, SB, TELOPT_LFLOW, flowmode ? LFLOW_ON : LFLOW_OFF, IAC, SE); - nfrontp += 6; } } pcc--; @@ -1505,19 +1486,19 @@ telnet(f, p, host) break; c = *ptyip++ & 0377, pcc--; if (c == IAC) - *nfrontp++ = c; + netprintf("%c", c); #if defined(CRAY2) && defined(UNICOS5) else if (c == '\n' && my_state_is_wont(TELOPT_BINARY) && newmap) - *nfrontp++ = '\r'; + netputs("\r"); #endif /* defined(CRAY2) && defined(UNICOS5) */ - *nfrontp++ = c; + netprintf("%c", c); if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) { if (pcc > 0 && ((*ptyip & 0377) == '\n')) { - *nfrontp++ = *ptyip++ & 0377; + netprintf("%c", *ptyip++ & 0377); pcc--; } else - *nfrontp++ = '\0'; + netprintf("%c", '\0'); } } #if defined(CRAY2) && defined(UNICOS5) @@ -1679,7 +1660,7 @@ sendsusp() * When we get an AYT, if ^T is enabled, use that. Otherwise, * just send back "[Yes]". */ - void +void recv_ayt() { #if defined(SIGINFO) && defined(TCSIG) @@ -1688,8 +1669,7 @@ recv_ayt() return; } #endif - (void) strcpy(nfrontp, "\r\n[Yes]\r\n"); - nfrontp += 9; + netputs("\r\n[Yes]\r\n"); } void diff --git a/src/appl/telnet/telnetd/termstat.c b/src/appl/telnet/telnetd/termstat.c index 824a1a6..531e167 100644 --- a/src/appl/telnet/telnetd/termstat.c +++ b/src/appl/telnet/telnetd/termstat.c @@ -283,10 +283,9 @@ localstat() # endif /* KLUDGELINEMODE */ send_do(TELOPT_LINEMODE, 1); /* send along edit modes */ - (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB, + netprintf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, LM_MODE, useeditmode, IAC, SE); - nfrontp += 7; editmode = useeditmode; # ifdef KLUDGELINEMODE } @@ -312,10 +311,9 @@ localstat() /* * Send along appropriate edit mode mask. */ - (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB, + (void) netprintf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, LM_MODE, useeditmode, IAC, SE); - nfrontp += 7; editmode = useeditmode; } @@ -359,20 +357,18 @@ flowstat() if (his_state_is_will(TELOPT_LFLOW)) { if (tty_flowmode() != flowmode) { flowmode = tty_flowmode(); - (void) sprintf(nfrontp, "%c%c%c%c%c%c", + netprintf("%c%c%c%c%c%c", IAC, SB, TELOPT_LFLOW, flowmode ? LFLOW_ON : LFLOW_OFF, IAC, SE); - nfrontp += 6; } if (tty_restartany() != restartany) { restartany = tty_restartany(); - (void) sprintf(nfrontp, "%c%c%c%c%c%c", + netprintf("%c%c%c%c%c%c", IAC, SB, TELOPT_LFLOW, restartany ? LFLOW_RESTART_ANY : LFLOW_RESTART_XON, IAC, SE); - nfrontp += 6; } } } @@ -445,10 +441,9 @@ clientstat(code, parm1, parm2) useeditmode |= MODE_SOFT_TAB; if (tty_islitecho()) useeditmode |= MODE_LIT_ECHO; - (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, + netprintf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, LM_MODE, - useeditmode, IAC, SE); - nfrontp += 7; + useeditmode, IAC, SE); editmode = useeditmode; } @@ -504,11 +499,10 @@ clientstat(code, parm1, parm2) set_termbuf(); if (!ack) { - (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, + netprintf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, LM_MODE, useeditmode|MODE_ACK, IAC, SE); - nfrontp += 7; } editmode = useeditmode; diff --git a/src/appl/telnet/telnetd/utility.c b/src/appl/telnet/telnetd/utility.c index 408c6f4..93a932d 100644 --- a/src/appl/telnet/telnetd/utility.c +++ b/src/appl/telnet/telnetd/utility.c @@ -33,6 +33,7 @@ /* based on @(#)utility.c 8.1 (Berkeley) 6/4/93 */ +#include <stdarg.h> #define PRINTOPTIONS #include "telnetd.h" @@ -58,8 +59,7 @@ ttloop() { void netflush(); - DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop\r\n"); - nfrontp += strlen(nfrontp);}); + DIAG(TD_REPORT, netputs("td: ttloop\r\n")); if (nfrontp-nbackp) { netflush(); } @@ -74,8 +74,7 @@ read_again: syslog(LOG_INFO, "ttloop: peer died: %m"); exit(1); } - DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop read %d chars\r\n", ncc); - nfrontp += strlen(nfrontp);}); + DIAG(TD_REPORT, netprintf("td: ttloop read %d chars\r\n", ncc)); netip = netibuf; telrcv(); /* state machine */ if (ncc > 0) { @@ -118,8 +117,7 @@ ptyflush() if ((n = pfrontp - pbackp) > 0) { DIAG((TD_REPORT | TD_PTYDATA), - { sprintf(nfrontp, "td: ptyflush %d chars\r\n", n); - nfrontp += strlen(nfrontp); }); + netprintf("td: ptyflush %d chars\r\n", n)); DIAG(TD_PTYDATA, printdata("pd", pbackp, n)); n = write(pty, pbackp, n); } @@ -244,18 +242,15 @@ netclear() * Send as much data as possible to the network, * handling requests for urgent data. */ - void +void netflush() { int n; extern int not42; if ((n = nfrontp - nbackp) > 0) { - DIAG(TD_REPORT, - { sprintf(nfrontp, "td: netflush %d chars\r\n", n); - n += strlen(nfrontp); /* get count first */ - nfrontp += strlen(nfrontp); /* then move pointer */ - }); + DIAG(TD_REPORT, {netprintf_noflush("td: netflush %d chars\r\n", n); + n = nfrontp - nbackp;}); #ifdef ENCRYPTION if (encrypt_output) { char *s = nclearto ? nclearto : nbackp; @@ -312,33 +307,131 @@ netflush() return; } /* end of netflush */ +/* + * L8_256(x) = log8(256**x), rounded up, including sign (for decimal + * strings too). log8(256) = 8/3, but we use integer math to round + * up. + */ +#define L8_256(x) (((x * 8 + 2) / 3) + 1) /* - * writenet + * netprintf * - * Just a handy little function to write a bit of raw data to the net. - * It will force a transmit of the buffer if necessary + * Do the equivalent of printf() to the NETOBUF "ring buffer", + * possibly calling netflush() if needed. * - * arguments - * ptr - A pointer to a character string to write - * len - How many bytes to write + * Thou shalt not call this with a "%s" format; use netputs instead. + * We also don't deal with floating point widths in here. */ - void -writenet(ptr, len) - register unsigned char *ptr; - register int len; +void +netprintf_ext(int noflush, int seturg, const char *fmt, va_list args) { - /* flush buffer if no room for new data) */ - if ((&netobuf[BUFSIZ] - nfrontp) < len) { - /* if this fails, don't worry, buffer is a little big */ - netflush(); + size_t remain; + size_t maxoutlen; + char buf[BUFSIZ]; + const char *cp; + int len; + + buf[0] = '\0'; /* nul-terminate */ + remain = sizeof(netobuf) - (nfrontp - netobuf); + for (maxoutlen = 0, cp = fmt; *cp; cp++) { + if (*cp == '%') + /* Ok so this is slightly overkill... */ + maxoutlen += L8_256(sizeof(long)); + else + maxoutlen++; } + if (maxoutlen >= sizeof(buf)) + return; /* highly unlikely */ - memcpy(nfrontp, ptr, len); +#ifdef HAVE_VSNPRINTF + len = vsnprintf(buf, sizeof(buf), fmt, args); +#else + len = vsprintf(buf, fmt, args); /* XXX need to fix for SunOS? */ +#endif + + /* + * The return value from sprintf()-like functions may be the + * number of characters that *would* have been output, not the + * number actually output. + */ + if (len <= 0 || len > sizeof(buf)) + return; + if (remain < len && !noflush) { + netflush(); + remain = sizeof(netobuf) - (nfrontp - netobuf); + } + if (remain < len) + return; /* still not enough space? */ + memcpy(nfrontp, buf, (size_t)len); nfrontp += len; + if (seturg) + neturg = nfrontp - 1; +} + +void +netprintf(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + netprintf_ext(0, 0, fmt, args); + va_end(args); +} + +void +netprintf_urg(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + netprintf_ext(0, 1, fmt, args); + va_end(args); +} + +void +netprintf_noflush(const char *fmt, ...) +{ + va_list args; -} /* end of writenet */ + va_start(args, fmt); + netprintf_ext(1, 0, fmt, args); + va_end(args); +} + +/* + * netwrite + * + * Copy BUF into the NETOBUF "ring buffer", possibly calling + * netflush() if needed. + */ +int +netwrite(const char *buf, size_t len) +{ + size_t remain; + + remain = sizeof(netobuf) - (nfrontp - netobuf); + if (remain < len) { + netflush(); + remain = sizeof(netobuf) - (nfrontp - netobuf); + } + if (remain < len) + return 0; + memcpy(nfrontp, buf, len); + nfrontp += len; + return len; +} +/* + * netputs + * + * Write S to the NETOBUF "ring buffer". Does not write a '\n'. + */ +void +netputs(const char *s) +{ + netwrite(s, strlen(s)); +} /* * miscellaneous functions doing a variety of little jobs follow ... @@ -522,22 +615,26 @@ putf(cp, where) /* * Print telnet options and commands in plain text, if possible. */ - void +void printoption(fmt, option) register char *fmt; register int option; { - if (TELOPT_OK(option)) - sprintf(nfrontp, "%s %s\r\n", fmt, TELOPT(option)); - else if (TELCMD_OK(option)) - sprintf(nfrontp, "%s %s\r\n", fmt, TELCMD(option)); - else - sprintf(nfrontp, "%s %d\r\n", fmt, option); - nfrontp += strlen(nfrontp); + netputs(fmt); + netputs(" "); + if (TELOPT_OK(option)) { + netputs(TELOPT(option)); + netputs("\r\n"); + } else if (TELCMD_OK(option)) { + netputs(TELCMD(option)); + netputs("\r\n"); + } else { + netprintf("%d\r\n", option); + } return; } - void +void printsub(direction, pointer, length) char direction; /* '<' or '>' */ unsigned char *pointer; /* where suboption data sits */ @@ -550,9 +647,9 @@ printsub(direction, pointer, length) return; if (direction) { - sprintf(nfrontp, "td: %s suboption ", - direction == '<' ? "recv" : "send"); - nfrontp += strlen(nfrontp); + netputs("td: "); + netputs(direction == '<' ? "recv" : "send"); + netputs(" suboption "); if (length >= 3) { register int j; @@ -560,261 +657,223 @@ printsub(direction, pointer, length) j = pointer[length-1]; if (i != IAC || j != SE) { - sprintf(nfrontp, "(terminated by "); - nfrontp += strlen(nfrontp); + netputs("(terminated by "); if (TELOPT_OK(i)) - sprintf(nfrontp, "%s ", TELOPT(i)); + netputs(TELOPT(i)); else if (TELCMD_OK(i)) - sprintf(nfrontp, "%s ", TELCMD(i)); + netputs(TELCMD(i)); else - sprintf(nfrontp, "%d ", i); - nfrontp += strlen(nfrontp); + netprintf("%d", i); + netputs(" "); if (TELOPT_OK(j)) - sprintf(nfrontp, "%s", TELOPT(j)); + netputs(TELOPT(j)); else if (TELCMD_OK(j)) - sprintf(nfrontp, "%s", TELCMD(j)); + netputs(TELCMD(j)); else - sprintf(nfrontp, "%d", j); - nfrontp += strlen(nfrontp); - sprintf(nfrontp, ", not IAC SE!) "); - nfrontp += strlen(nfrontp); + netprintf("%d", j); + netputs(", not IAC SE!) "); } } length -= 2; } if (length < 1) { - sprintf(nfrontp, "(Empty suboption??\?)"); - nfrontp += strlen(nfrontp); + netputs("(Empty suboption??\?)"); return; } switch (pointer[0]) { case TELOPT_TTYPE: - sprintf(nfrontp, "TERMINAL-TYPE "); - nfrontp += strlen(nfrontp); + netputs("TERMINAL-TYPE "); switch (pointer[1]) { case TELQUAL_IS: - sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2); + netputs("IS \""); + netwrite((char *)pointer + 2, (size_t)(length - 2)); + netputs("\""); break; case TELQUAL_SEND: - sprintf(nfrontp, "SEND"); + netputs("SEND"); break; default: - sprintf(nfrontp, - "- unknown qualifier %d (0x%x).", - pointer[1], pointer[1]); + netprintf("- unknown qualifier %d (0x%x).", + pointer[1], pointer[1]); } - nfrontp += strlen(nfrontp); break; case TELOPT_TSPEED: - sprintf(nfrontp, "TERMINAL-SPEED"); - nfrontp += strlen(nfrontp); + netputs("TERMINAL-SPEED "); if (length < 2) { - sprintf(nfrontp, " (empty suboption??\?)"); - nfrontp += strlen(nfrontp); + netputs("(empty suboption??\?)"); break; } switch (pointer[1]) { case TELQUAL_IS: - sprintf(nfrontp, " IS %.*s", length-2, (char *)pointer+2); - nfrontp += strlen(nfrontp); + netputs("IS "); + netwrite((char *)pointer + 2, (size_t)(length - 2)); break; default: if (pointer[1] == 1) - sprintf(nfrontp, " SEND"); + netputs("SEND"); else - sprintf(nfrontp, " %d (unknown)", pointer[1]); - nfrontp += strlen(nfrontp); - for (i = 2; i < length; i++) { - sprintf(nfrontp, " ?%d?", pointer[i]); - nfrontp += strlen(nfrontp); - } + netprintf("%d (unknown)", pointer[1]); + for (i = 2; i < length; i++) + netprintf(" ?%d?", pointer[i]); break; } break; case TELOPT_LFLOW: - sprintf(nfrontp, "TOGGLE-FLOW-CONTROL"); - nfrontp += strlen(nfrontp); + netputs("TOGGLE-FLOW-CONTROL "); if (length < 2) { - sprintf(nfrontp, " (empty suboption??\?)"); - nfrontp += strlen(nfrontp); + netputs("(empty suboption??\?)"); break; } switch (pointer[1]) { case LFLOW_OFF: - sprintf(nfrontp, " OFF"); break; + netputs("OFF"); break; case LFLOW_ON: - sprintf(nfrontp, " ON"); break; + netputs("ON"); break; case LFLOW_RESTART_ANY: - sprintf(nfrontp, " RESTART-ANY"); break; + netputs("RESTART-ANY"); break; case LFLOW_RESTART_XON: - sprintf(nfrontp, " RESTART-XON"); break; + netputs("RESTART-XON"); break; default: - sprintf(nfrontp, " %d (unknown)", pointer[1]); - } - nfrontp += strlen(nfrontp); - for (i = 2; i < length; i++) { - sprintf(nfrontp, " ?%d?", pointer[i]); - nfrontp += strlen(nfrontp); + netprintf("%d (unknown)", pointer[1]); } + for (i = 2; i < length; i++) + netprintf(" ?%d?", pointer[i]); break; case TELOPT_NAWS: - sprintf(nfrontp, "NAWS"); - nfrontp += strlen(nfrontp); + netputs("NAWS"); if (length < 2) { - sprintf(nfrontp, " (empty suboption??\?)"); - nfrontp += strlen(nfrontp); + netputs(" (empty suboption??\?)"); break; } if (length == 2) { - sprintf(nfrontp, " ?%d?", pointer[1]); - nfrontp += strlen(nfrontp); + netprintf(" ?%d?", pointer[1]); break; } - sprintf(nfrontp, " %d %d (%d)", + netprintf(" %d %d (%d)", pointer[1], pointer[2], (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); - nfrontp += strlen(nfrontp); if (length == 4) { - sprintf(nfrontp, " ?%d?", pointer[3]); - nfrontp += strlen(nfrontp); + netprintf(" ?%d?", pointer[3]); break; } - sprintf(nfrontp, " %d %d (%d)", + netprintf(" %d %d (%d)", pointer[3], pointer[4], (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); - nfrontp += strlen(nfrontp); - for (i = 5; i < length; i++) { - sprintf(nfrontp, " ?%d?", pointer[i]); - nfrontp += strlen(nfrontp); - } + for (i = 5; i < length; i++) + netprintf(" ?%d?", pointer[i]); break; case TELOPT_LINEMODE: - sprintf(nfrontp, "LINEMODE "); - nfrontp += strlen(nfrontp); + netputs("LINEMODE "); if (length < 2) { - sprintf(nfrontp, " (empty suboption??\?)"); - nfrontp += strlen(nfrontp); + netputs("(empty suboption??\?)"); break; } switch (pointer[1]) { case WILL: - sprintf(nfrontp, "WILL "); + netputs("WILL "); goto common; case WONT: - sprintf(nfrontp, "WONT "); + netputs("WONT "); goto common; case DO: - sprintf(nfrontp, "DO "); + netputs("DO "); goto common; case DONT: - sprintf(nfrontp, "DONT "); + netputs("DONT "); common: - nfrontp += strlen(nfrontp); if (length < 3) { - sprintf(nfrontp, "(no option??\?)"); - nfrontp += strlen(nfrontp); + netputs("(no option??\?)"); break; } switch (pointer[2]) { case LM_FORWARDMASK: - sprintf(nfrontp, "Forward Mask"); - nfrontp += strlen(nfrontp); - for (i = 3; i < length; i++) { - sprintf(nfrontp, " %x", pointer[i]); - nfrontp += strlen(nfrontp); - } + netputs("Forward Mask"); + for (i = 3; i < length; i++) + netprintf(" %x", pointer[i]); break; default: - sprintf(nfrontp, "%d (unknown)", pointer[2]); - nfrontp += strlen(nfrontp); - for (i = 3; i < length; i++) { - sprintf(nfrontp, " %d", pointer[i]); - nfrontp += strlen(nfrontp); - } + netprintf("%d (unknown)", pointer[2]); + for (i = 3; i < length; i++) + netprintf(" %d", pointer[i]); break; } break; case LM_SLC: - sprintf(nfrontp, "SLC"); - nfrontp += strlen(nfrontp); + netputs("SLC"); for (i = 2; i < length - 2; i += 3) { - if (SLC_NAME_OK(pointer[i+SLC_FUNC])) - sprintf(nfrontp, " %s", SLC_NAME(pointer[i+SLC_FUNC])); - else - sprintf(nfrontp, " %d", pointer[i+SLC_FUNC]); - nfrontp += strlen(nfrontp); + if (SLC_NAME_OK(pointer[i+SLC_FUNC])) { + netputs(" "); + netputs(SLC_NAME(pointer[i+SLC_FUNC])); + } else + netprintf(" %d", pointer[i+SLC_FUNC]); switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { case SLC_NOSUPPORT: - sprintf(nfrontp, " NOSUPPORT"); break; + netputs(" NOSUPPORT"); break; case SLC_CANTCHANGE: - sprintf(nfrontp, " CANTCHANGE"); break; + netputs(" CANTCHANGE"); break; case SLC_VARIABLE: - sprintf(nfrontp, " VARIABLE"); break; + netputs(" VARIABLE"); break; case SLC_DEFAULT: - sprintf(nfrontp, " DEFAULT"); break; + netputs(" DEFAULT"); break; } - nfrontp += strlen(nfrontp); - sprintf(nfrontp, "%s%s%s", - pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", - pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", - pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); - nfrontp += strlen(nfrontp); + netputs(pointer[i+SLC_FLAGS]&SLC_ACK + ? "|ACK" : ""); + netputs(pointer[i+SLC_FLAGS]&SLC_FLUSHIN + ? "|FLUSHIN" : ""); + netputs(pointer[i+SLC_FLAGS]&SLC_FLUSHOUT + ? "|FLUSHOUT" : ""); if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| SLC_FLUSHOUT| SLC_LEVELBITS)) { - sprintf(nfrontp, "(0x%x)", pointer[i+SLC_FLAGS]); - nfrontp += strlen(nfrontp); + netprintf("(0x%x)", pointer[i+SLC_FLAGS]); } - sprintf(nfrontp, " %d;", pointer[i+SLC_VALUE]); - nfrontp += strlen(nfrontp); + netprintf(" %d;", pointer[i+SLC_VALUE]); if ((pointer[i+SLC_VALUE] == IAC) && (pointer[i+SLC_VALUE+1] == IAC)) i++; } - for (; i < length; i++) { - sprintf(nfrontp, " ?%d?", pointer[i]); - nfrontp += strlen(nfrontp); - } + for (; i < length; i++) + netprintf(" ?%d?", pointer[i]); break; case LM_MODE: - sprintf(nfrontp, "MODE "); - nfrontp += strlen(nfrontp); + netputs("MODE "); if (length < 3) { - sprintf(nfrontp, "(no mode??\?)"); - nfrontp += strlen(nfrontp); + netputs("(no mode??\?)"); break; } { - char tbuf[32]; - sprintf(tbuf, "%s%s%s%s%s", - pointer[2]&MODE_EDIT ? "|EDIT" : "", - pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", - pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", - pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", - pointer[2]&MODE_ACK ? "|ACK" : ""); - sprintf(nfrontp, "%s", tbuf[1] ? &tbuf[1] : "0"); - nfrontp += strlen(nfrontp); - } - if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) { - sprintf(nfrontp, " (0x%x)", pointer[2]); - nfrontp += strlen(nfrontp); - } - for (i = 3; i < length; i++) { - sprintf(nfrontp, " ?0x%x?", pointer[i]); - nfrontp += strlen(nfrontp); + int wrotemode = 0; + +#define NETPUTS_MODE(x) \ +do { \ + if (pointer[2] & (MODE_##x)) { \ + if (wrotemode) netputs("|"); \ + netputs(#x); \ + wrotemode++; \ + } \ +} while (0) + NETPUTS_MODE(EDIT); + NETPUTS_MODE(TRAPSIG); + NETPUTS_MODE(SOFT_TAB); + NETPUTS_MODE(LIT_ECHO); + NETPUTS_MODE(ACK); +#undef NETPUTS_MODE + if (!wrotemode) + netputs("0"); } + if (pointer[2] & ~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) + netprintf(" (0x%x)", pointer[2]); + for (i = 3; i < length; i++) + netprintf(" ?0x%x?", pointer[i]); break; default: - sprintf(nfrontp, "%d (unknown)", pointer[1]); - nfrontp += strlen(nfrontp); - for (i = 2; i < length; i++) { - sprintf(nfrontp, " %d", pointer[i]); - nfrontp += strlen(nfrontp); - } + netprintf("%d (unknown)", pointer[1]); + for (i = 2; i < length; i++) + netprintf(" %d", pointer[i]); } break; @@ -822,24 +881,19 @@ printsub(direction, pointer, length) register char *cp; register int j, k; - sprintf(nfrontp, "STATUS"); - nfrontp += strlen(nfrontp); + netputs("STATUS"); switch (pointer[1]) { default: if (pointer[1] == TELQUAL_SEND) - sprintf(nfrontp, " SEND"); + netputs(" SEND"); else - sprintf(nfrontp, " %d (unknown)", pointer[1]); - nfrontp += strlen(nfrontp); - for (i = 2; i < length; i++) { - sprintf(nfrontp, " ?%d?", pointer[i]); - nfrontp += strlen(nfrontp); - } + netprintf(" %d (unknown)", pointer[1]); + for (i = 2; i < length; i++) + netprintf(" ?%d?", pointer[i]); break; case TELQUAL_IS: - sprintf(nfrontp, " IS\r\n"); - nfrontp += strlen(nfrontp); + netputs(" IS\r\n"); for (i = 2; i < length; i++) { switch(pointer[i]) { @@ -849,19 +903,19 @@ printsub(direction, pointer, length) case WONT: cp = "WONT"; goto common2; common2: i++; + netputs(" "); + netputs(cp); + netputs(" "); if (TELOPT_OK(pointer[i])) - sprintf(nfrontp, " %s %s", cp, TELOPT(pointer[i])); + netputs(TELOPT(pointer[i])); else - sprintf(nfrontp, " %s %d", cp, pointer[i]); - nfrontp += strlen(nfrontp); + netprintf("%d", pointer[i]); - sprintf(nfrontp, "\r\n"); - nfrontp += strlen(nfrontp); + netputs("\r\n"); break; case SB: - sprintf(nfrontp, " SB "); - nfrontp += strlen(nfrontp); + netputs(" SB "); i++; j = k = i; while (j < length) { @@ -877,20 +931,17 @@ printsub(direction, pointer, length) } printsub(0, &pointer[i], k - i); if (i < length) { - sprintf(nfrontp, " SE"); - nfrontp += strlen(nfrontp); + netputs(" SE"); i = j; } else i = j - 1; - sprintf(nfrontp, "\r\n"); - nfrontp += strlen(nfrontp); + netputs("\r\n"); break; default: - sprintf(nfrontp, " %d", pointer[i]); - nfrontp += strlen(nfrontp); + netprintf(" %d", pointer[i]); break; } } @@ -900,86 +951,79 @@ printsub(direction, pointer, length) } case TELOPT_XDISPLOC: - sprintf(nfrontp, "X-DISPLAY-LOCATION "); - nfrontp += strlen(nfrontp); + netputs("X-DISPLAY-LOCATION "); switch (pointer[1]) { case TELQUAL_IS: - sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2); + netputs("IS \""); + netwrite((char *)pointer + 2, (size_t)(length - 2)); + netputs("\""); break; case TELQUAL_SEND: - sprintf(nfrontp, "SEND"); + netputs("SEND"); break; default: - sprintf(nfrontp, "- unknown qualifier %d (0x%x).", - pointer[1], pointer[1]); + netprintf("- unknown qualifier %d (0x%x).", + pointer[1], pointer[1]); } - nfrontp += strlen(nfrontp); break; case TELOPT_NEW_ENVIRON: - sprintf(nfrontp, "NEW-ENVIRON "); + netputs("NEW-ENVIRON "); goto env_common1; case TELOPT_OLD_ENVIRON: - sprintf(nfrontp, "OLD-ENVIRON"); + netputs("OLD-ENVIRON "); env_common1: - nfrontp += strlen(nfrontp); switch (pointer[1]) { case TELQUAL_IS: - sprintf(nfrontp, "IS "); + netputs("IS "); goto env_common; case TELQUAL_SEND: - sprintf(nfrontp, "SEND "); + netputs("SEND "); goto env_common; case TELQUAL_INFO: - sprintf(nfrontp, "INFO "); + netputs("INFO "); env_common: - nfrontp += strlen(nfrontp); { register int noquote = 2; for (i = 2; i < length; i++ ) { switch (pointer[i]) { case NEW_ENV_VAR: - sprintf(nfrontp, "\" VAR " + noquote); - nfrontp += strlen(nfrontp); + netputs("\" VAR " + noquote); noquote = 2; break; case NEW_ENV_VALUE: - sprintf(nfrontp, "\" VALUE " + noquote); - nfrontp += strlen(nfrontp); + netputs("\" VALUE " + noquote); noquote = 2; break; case ENV_ESC: - sprintf(nfrontp, "\" ESC " + noquote); - nfrontp += strlen(nfrontp); + netputs("\" ESC " + noquote); noquote = 2; break; case ENV_USERVAR: - sprintf(nfrontp, "\" USERVAR " + noquote); - nfrontp += strlen(nfrontp); + netputs("\" USERVAR " + noquote); noquote = 2; break; default: if (isprint(pointer[i]) && pointer[i] != '"') { if (noquote) { - *nfrontp++ = '"'; + netputs("\""); noquote = 0; } - *nfrontp++ = pointer[i]; + netprintf("%c", pointer[i]); } else { - sprintf(nfrontp, "\" %03o " + noquote, - pointer[i]); - nfrontp += strlen(nfrontp); + netprintf("\" %03o " + noquote, + pointer[i]); noquote = 2; } break; } } if (!noquote) - *nfrontp++ = '"'; + netputs("\""); break; } } @@ -987,91 +1031,74 @@ printsub(direction, pointer, length) #if defined(AUTHENTICATION) case TELOPT_AUTHENTICATION: - sprintf(nfrontp, "AUTHENTICATION"); - nfrontp += strlen(nfrontp); + netputs("AUTHENTICATION"); if (length < 2) { - sprintf(nfrontp, " (empty suboption??\?)"); - nfrontp += strlen(nfrontp); + netputs(" (empty suboption??\?)"); break; } switch (pointer[1]) { case TELQUAL_REPLY: case TELQUAL_IS: - sprintf(nfrontp, " %s ", (pointer[1] == TELQUAL_IS) ? - "IS" : "REPLY"); - nfrontp += strlen(nfrontp); + netputs((pointer[1] == TELQUAL_IS) ? " IS " : " REPLY "); if (AUTHTYPE_NAME_OK(pointer[2])) - sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[2])); + netputs(AUTHTYPE_NAME(pointer[2])); else - sprintf(nfrontp, "%d ", pointer[2]); - nfrontp += strlen(nfrontp); + netprintf(" %d ", pointer[2]); if (length < 3) { - sprintf(nfrontp, "(partial suboption??\?)"); - nfrontp += strlen(nfrontp); + netputs("(partial suboption??\?)"); break; } - sprintf(nfrontp, "%s|%s%s", - ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? - "CLIENT" : "SERVER", - ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? - "MUTUAL" : "ONE-WAY", - ((pointer[3] & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON) ? - "|ENCRYPT" : ""); - nfrontp += strlen(nfrontp); + netputs(((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) + ? "CLIENT|" : "SERVER|"); + netputs(((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) + ? "MUTUAL" : "ONE-WAY"); + netputs(((pointer[3] & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON) + ? "|ENCRYPT" : ""); auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); - sprintf(nfrontp, "%s", buf); - nfrontp += strlen(nfrontp); + netputs(buf); break; case TELQUAL_SEND: i = 2; - sprintf(nfrontp, " SEND "); - nfrontp += strlen(nfrontp); + netputs(" SEND "); while (i < length) { if (AUTHTYPE_NAME_OK(pointer[i])) - sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[i])); + netputs(AUTHTYPE_NAME(pointer[i])); else - sprintf(nfrontp, "%d ", pointer[i]); - nfrontp += strlen(nfrontp); + netprintf("%d", pointer[i]); + netputs(" "); if (++i >= length) { - sprintf(nfrontp, "(partial suboption??\?)"); - nfrontp += strlen(nfrontp); + netputs("(partial suboption??\?)"); break; } - sprintf(nfrontp, "%s|%s%s ", - ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? - "CLIENT" : "SERVER", - ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? - "MUTUAL" : "ONE-WAY", - ((pointer[3] & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON) ? - "|ENCRYPT" : ""); - nfrontp += strlen(nfrontp); + netputs(((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) + ? "CLIENT|" : "SERVER|"); + netputs(((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) + ? "MUTUAL" : "ONE-WAY"); + if ((pointer[3] & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON) + netputs("|ENCRYPT"); ++i; } break; case TELQUAL_NAME: i = 2; - sprintf(nfrontp, " NAME \""); - nfrontp += strlen(nfrontp); + netputs(" NAME \""); while (i < length) { if (isprint(pointer[i])) - *nfrontp++ = pointer[i++]; + netprintf("%c", pointer[i++]); else { - sprintf(nfrontp, "\"%03o",pointer[i++]); - nfrontp += strlen(nfrontp); + netprintf("\\%03o", pointer[i++]); } } - *nfrontp++ = '"'; + netputs("\""); break; default: - for (i = 2; i < length; i++) { - sprintf(nfrontp, " ?%d?", pointer[i]); - nfrontp += strlen(nfrontp); - } + for (i = 2; i < length; i++) + netprintf(" ?%d?", pointer[i]); break; } break; @@ -1079,87 +1106,72 @@ printsub(direction, pointer, length) #ifdef ENCRYPTION case TELOPT_ENCRYPT: - sprintf(nfrontp, "ENCRYPT"); - nfrontp += strlen(nfrontp); + netputs("ENCRYPT"); if (length < 2) { - sprintf(nfrontp, " (empty suboption??\?)"); - nfrontp += strlen(nfrontp); + netputs(" (empty suboption??\?)"); break; } switch (pointer[1]) { case ENCRYPT_START: - sprintf(nfrontp, " START"); - nfrontp += strlen(nfrontp); + netputs(" START"); break; case ENCRYPT_END: - sprintf(nfrontp, " END"); - nfrontp += strlen(nfrontp); + netputs(" END"); break; case ENCRYPT_REQSTART: - sprintf(nfrontp, " REQUEST-START"); - nfrontp += strlen(nfrontp); + netputs(" REQUEST-START"); break; case ENCRYPT_REQEND: - sprintf(nfrontp, " REQUEST-END"); - nfrontp += strlen(nfrontp); + netputs(" REQUEST-END"); break; case ENCRYPT_IS: case ENCRYPT_REPLY: - sprintf(nfrontp, " %s ", (pointer[1] == ENCRYPT_IS) ? - "IS" : "REPLY"); - nfrontp += strlen(nfrontp); + netputs((pointer[1] == ENCRYPT_IS) + ? " IS " : " REPLY "); if (length < 3) { - sprintf(nfrontp, " (partial suboption??\?)"); - nfrontp += strlen(nfrontp); + netputs(" (partial suboption??\?)"); break; } if (ENCTYPE_NAME_OK(pointer[2])) - sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[2])); + netputs(ENCTYPE_NAME(pointer[2])); else - sprintf(nfrontp, " %d (unknown)", pointer[2]); - nfrontp += strlen(nfrontp); + netprintf("%d (unknown)", pointer[2]); + netputs(" "); encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf)); - sprintf(nfrontp, "%s", buf); - nfrontp += strlen(nfrontp); + netputs(buf); break; case ENCRYPT_SUPPORT: i = 2; - sprintf(nfrontp, " SUPPORT "); - nfrontp += strlen(nfrontp); + netputs(" SUPPORT "); while (i < length) { if (ENCTYPE_NAME_OK(pointer[i])) - sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[i])); + netputs(ENCTYPE_NAME(pointer[i])); else - sprintf(nfrontp, "%d ", pointer[i]); - nfrontp += strlen(nfrontp); + netprintf("%d", pointer[i]); + netputs(" "); i++; } break; case ENCRYPT_ENC_KEYID: - sprintf(nfrontp, " ENC_KEYID", pointer[1]); - nfrontp += strlen(nfrontp); + netputs(" ENC_KEYID"); goto encommon; case ENCRYPT_DEC_KEYID: - sprintf(nfrontp, " DEC_KEYID", pointer[1]); - nfrontp += strlen(nfrontp); + netputs(" DEC_KEYID"); goto encommon; default: - sprintf(nfrontp, " %d (unknown)", pointer[1]); - nfrontp += strlen(nfrontp); + netprintf(" %d (unknown)", pointer[1]); encommon: - for (i = 2; i < length; i++) { - sprintf(nfrontp, " %d", pointer[i]); - nfrontp += strlen(nfrontp); - } + for (i = 2; i < length; i++) + netprintf(" %d", pointer[i]); break; } break; @@ -1167,18 +1179,15 @@ printsub(direction, pointer, length) default: if (TELOPT_OK(pointer[0])) - sprintf(nfrontp, "%s (unknown)", TELOPT(pointer[0])); + netputs(TELOPT(pointer[0])); else - sprintf(nfrontp, "%d (unknown)", pointer[i]); - nfrontp += strlen(nfrontp); - for (i = 1; i < length; i++) { - sprintf(nfrontp, " %d", pointer[i]); - nfrontp += strlen(nfrontp); - } + netprintf("%d", pointer[0]); + netputs(" (unknown)"); + for (i = 1; i < length; i++) + netprintf(" %d", pointer[i]); break; } - sprintf(nfrontp, "\r\n"); - nfrontp += strlen(nfrontp); + netputs("\r\n"); } /* @@ -1194,32 +1203,25 @@ printdata(tag, ptr, cnt) char xbuf[30]; while (cnt) { - /* flush net output buffer if no room for new data) */ - if ((&netobuf[BUFSIZ] - nfrontp) < 80) { - netflush(); - } - /* add a line of output */ - sprintf(nfrontp, "%s: ", tag); - nfrontp += strlen(nfrontp); + netputs(tag); + netputs(": "); for (i = 0; i < 20 && cnt; i++) { - sprintf(nfrontp, "%02x", *ptr); - nfrontp += strlen(nfrontp); + netprintf("%02x", *ptr); if (isprint(*ptr)) { xbuf[i] = *ptr; } else { xbuf[i] = '.'; } - if (i % 2) { - *nfrontp = ' '; - nfrontp++; - } + if (i % 2) + netputs(" "); cnt--; ptr++; } xbuf[i] = '\0'; - sprintf(nfrontp, " %s\r\n", xbuf ); - nfrontp += strlen(nfrontp); + netputs(" "); + netputs(xbuf); + netputs("\r\n"); } } #endif /* DIAGNOSTICS */ |