diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2005-02-27 15:46:43 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2005-02-27 15:46:43 +0000 |
commit | 5df29dba0aaa8b713981d5052ffbdb2842096a9d (patch) | |
tree | 46df7f4866f5b3706f63837d8895c4589b6f55c5 /usr.bin/telnet | |
parent | 92dce8543dd408cbcfbf15fb6eae100f6d577ff3 (diff) |
- only send exported vars (based on a diff from Solar Designer)
- fix some buffer overflows (also some Solar Designer input)
ok deraadt@ cloder@
Diffstat (limited to 'usr.bin/telnet')
-rw-r--r-- | usr.bin/telnet/authenc.c | 6 | ||||
-rw-r--r-- | usr.bin/telnet/commands.c | 7 | ||||
-rw-r--r-- | usr.bin/telnet/externs.h | 6 | ||||
-rw-r--r-- | usr.bin/telnet/telnet.c | 121 |
4 files changed, 84 insertions, 56 deletions
diff --git a/usr.bin/telnet/authenc.c b/usr.bin/telnet/authenc.c index 2b8cae647ec..8aa46027e32 100644 --- a/usr.bin/telnet/authenc.c +++ b/usr.bin/telnet/authenc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authenc.c,v 1.6 2003/06/03 02:56:18 millert Exp $ */ +/* $OpenBSD: authenc.c,v 1.7 2005/02/27 15:46:42 otto Exp $ */ /* $NetBSD: authenc.c,v 1.5 1996/02/28 21:03:52 thorpej Exp $ */ /*- @@ -31,7 +31,7 @@ */ /* -RCSID("$Id: authenc.c,v 1.6 2003/06/03 02:56:18 millert Exp $"); +RCSID("$Id: authenc.c,v 1.7 2005/02/27 15:46:42 otto Exp $"); */ #include "telnet_locl.h" @@ -80,7 +80,7 @@ telnet_spin() telnet_getenv(val) const char *val; { - return((char *)env_getvalue((unsigned char *)val)); + return((char *)env_getvalue((unsigned char *)val, 0)); } char * diff --git a/usr.bin/telnet/commands.c b/usr.bin/telnet/commands.c index 5ee299d498f..0642f4d5c6a 100644 --- a/usr.bin/telnet/commands.c +++ b/usr.bin/telnet/commands.c @@ -1,4 +1,4 @@ -/* $OpenBSD: commands.c,v 1.47 2004/11/17 01:47:20 itojun Exp $ */ +/* $OpenBSD: commands.c,v 1.48 2005/02/27 15:46:42 otto Exp $ */ /* $NetBSD: commands.c,v 1.14 1996/03/24 22:03:48 jtk Exp $ */ /* @@ -1821,12 +1821,13 @@ env_default(init, welldefined) } unsigned char * -env_getvalue(var) +env_getvalue(var, exported_only) unsigned char *var; + int exported_only; { struct env_lst *ep; - if ((ep = env_find(var))) + if ((ep = env_find(var)) && (!exported_only || ep->export)) return(ep->value); return(NULL); } diff --git a/usr.bin/telnet/externs.h b/usr.bin/telnet/externs.h index 9e28a456f6e..d15e1ce985e 100644 --- a/usr.bin/telnet/externs.h +++ b/usr.bin/telnet/externs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: externs.h,v 1.13 2004/01/03 23:36:14 pvalchev Exp $ */ +/* $OpenBSD: externs.h,v 1.14 2005/02/27 15:46:42 otto Exp $ */ /* $KTH: externs.h,v 1.16 1997/11/29 02:28:35 joda Exp $ */ /* @@ -204,7 +204,7 @@ void env_unexport (unsigned char *); void env_send (unsigned char *); void env_list (void); unsigned char * env_default(int init, int welldefined); -unsigned char * env_getvalue(unsigned char *var); +unsigned char * env_getvalue(unsigned char *var, int exported_only); void set_escape_char(char *s); unsigned long sourceroute(char *arg, char **cpp, int *lenp); @@ -336,7 +336,7 @@ void env_opt_add (unsigned char *); void env_opt_end (int); unsigned char *env_default (int, int); -unsigned char *env_getvalue (unsigned char *); +unsigned char *env_getvalue (unsigned char *, int); int get_status (void); int dosynch (void); diff --git a/usr.bin/telnet/telnet.c b/usr.bin/telnet/telnet.c index 4db0706384f..c1d536f5a42 100644 --- a/usr.bin/telnet/telnet.c +++ b/usr.bin/telnet/telnet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: telnet.c,v 1.18 2003/11/08 19:17:29 jmc Exp $ */ +/* $OpenBSD: telnet.c,v 1.19 2005/02/27 15:46:42 otto Exp $ */ /* $NetBSD: telnet.c,v 1.7 1996/02/28 21:04:15 thorpej Exp $ */ /* @@ -446,7 +446,7 @@ dooption(option) #endif case TELOPT_XDISPLOC: /* X Display location */ - if (env_getvalue((unsigned char *)"DISPLAY")) + if (env_getvalue((unsigned char *)"DISPLAY", 0)) new_state_ok = 1; break; @@ -682,7 +682,7 @@ gettermname() resettermname = 0; if (tnamep && tnamep != unknown) free(tnamep); - if ((tname = (char *)env_getvalue((unsigned char *)"TERM")) && + if ((tname = (char *)env_getvalue((unsigned char *)"TERM", 0)) && (setupterm(tname, 1, &errret) == OK)) { tnamep = mklist(ttytype, tname); } else { @@ -859,7 +859,7 @@ suboption() unsigned char temp[50], *dp; int len; - if ((dp = env_getvalue((unsigned char *)"DISPLAY")) == NULL) { + if ((dp = env_getvalue((unsigned char *)"DISPLAY", 0)) == NULL) { /* * Something happened, we no longer have a DISPLAY * variable. So, turn off the option. @@ -1331,17 +1331,25 @@ slc_check() } -unsigned char slc_reply[128]; -unsigned char *slc_replyp; +static unsigned char slc_reply[2 * SUBBUFSIZE]; +static unsigned char *slc_replyp; + + unsigned char +slc_add(unsigned char ch) +{ + if (slc_replyp == slc_reply + sizeof(slc_reply)) + return ch; + return *slc_replyp++ = ch; +} void slc_start_reply() { slc_replyp = slc_reply; - *slc_replyp++ = IAC; - *slc_replyp++ = SB; - *slc_replyp++ = TELOPT_LINEMODE; - *slc_replyp++ = LM_SLC; + slc_add(IAC); + slc_add(SB); + slc_add(TELOPT_LINEMODE); + slc_add(LM_SLC); } void @@ -1350,12 +1358,16 @@ slc_add_reply(func, flags, value) unsigned char flags; cc_t value; { - if ((*slc_replyp++ = func) == IAC) - *slc_replyp++ = IAC; - if ((*slc_replyp++ = flags) == IAC) - *slc_replyp++ = IAC; - if ((*slc_replyp++ = (unsigned char)value) == IAC) - *slc_replyp++ = IAC; + if (slc_replyp + 6 >= slc_reply + sizeof(slc_reply)) { + printf("slc_add_reply: not enough room\n"); + return; + } + if (slc_add(func) == IAC) + slc_add(IAC); + if (slc_add(flags) == IAC) + slc_add(IAC); + if (slc_add((unsigned char)value) == IAC) + slc_add(IAC); } void @@ -1363,8 +1375,13 @@ slc_end_reply() { int len; - *slc_replyp++ = IAC; - *slc_replyp++ = SE; + if (slc_replyp + 2 >= slc_reply + sizeof(slc_reply)) { + printf("slc_end_reply: not enough room\n"); + return; + } + + slc_add(IAC); + slc_add(SE); len = slc_replyp - slc_reply; if (len <= 6) return; @@ -1482,12 +1499,19 @@ env_opt(buf, len) } } -#define OPT_REPLY_SIZE 256 -unsigned char *opt_reply; -unsigned char *opt_replyp; -unsigned char *opt_replyend; +#define OPT_REPLY_SIZE (2 * SUBBUFSIZE) +static unsigned char *opt_reply; +static unsigned char *opt_replyp; +static unsigned char *opt_replyend; void +opt_add(unsigned char ch) +{ + if (opt_replyp == opt_replyend) + return; + *opt_replyp++ = ch; +} + void env_opt_start() { unsigned char *p; @@ -1506,10 +1530,10 @@ env_opt_start() } opt_replyp = opt_reply; opt_replyend = opt_reply + OPT_REPLY_SIZE; - *opt_replyp++ = IAC; - *opt_replyp++ = SB; - *opt_replyp++ = telopt_environ; - *opt_replyp++ = TELQUAL_IS; + opt_add(IAC); + opt_add(SB); + opt_add(telopt_environ); + opt_add(TELQUAL_IS); } void @@ -1541,57 +1565,60 @@ env_opt_add(ep) env_opt_add(ep); return; } - vp = env_getvalue(ep); - if (opt_replyp + (vp ? strlen((char *)vp) : 0) + - strlen((char *)ep) + 6 > opt_replyend) + vp = env_getvalue(ep, 1); + if (opt_replyp + 2 * (vp ? strlen((char *)vp) : 0) + + 2 * strlen((char *)ep) + 6 > opt_replyend) { - int len; + size_t len; unsigned char *p; - opt_replyend += OPT_REPLY_SIZE; + len = opt_replyend - opt_reply; + len += OPT_REPLY_SIZE + 2 * strlen(ep); + if (vp) + len += 2 * strlen(vp); p = (unsigned char *)realloc(opt_reply, len); - if (p == NULL) + if (p == NULL) { free(opt_reply); - opt_reply = p; - if (opt_reply == NULL) { /*@*/ printf("env_opt_add: realloc() failed!!!\n"); opt_reply = opt_replyp = opt_replyend = NULL; return; } - opt_replyp = opt_reply + len - (opt_replyend - opt_replyp); - opt_replyend = opt_reply + len; + opt_replyp = p + (opt_replyp - opt_reply); + opt_replyend = p + len; + opt_reply = p; } if (opt_welldefined((char *)ep)) #ifdef OLD_ENVIRON if (telopt_environ == TELOPT_OLD_ENVIRON) - *opt_replyp++ = old_env_var; + opt_add(old_env_var); else #endif - *opt_replyp++ = NEW_ENV_VAR; + opt_add(NEW_ENV_VAR); else - *opt_replyp++ = ENV_USERVAR; + opt_add(ENV_USERVAR); + for (;;) { while ((c = *ep++)) { switch(c&0xff) { case IAC: - *opt_replyp++ = IAC; + opt_add(IAC); break; case NEW_ENV_VAR: case NEW_ENV_VALUE: case ENV_ESC: case ENV_USERVAR: - *opt_replyp++ = ENV_ESC; + opt_add(ENV_ESC); break; } - *opt_replyp++ = c; + opt_add(c); } if ((ep = vp)) { #ifdef OLD_ENVIRON if (telopt_environ == TELOPT_OLD_ENVIRON) - *opt_replyp++ = old_env_value; + opt_add(old_env_value); else #endif - *opt_replyp++ = NEW_ENV_VALUE; + opt_add(NEW_ENV_VALUE); vp = NULL; } else break; @@ -1619,8 +1646,8 @@ env_opt_end(emptyok) len = opt_replyp - opt_reply + 2; if (emptyok || len > 6) { - *opt_replyp++ = IAC; - *opt_replyp++ = SE; + opt_add(IAC); + opt_add(SE); if (NETROOM() > len) { ring_supply_data(&netoring, opt_reply, len); printsub('>', &opt_reply[2], len - 2); @@ -2197,7 +2224,7 @@ telnet(user) send_will(TELOPT_LINEMODE, 1); send_will(TELOPT_NEW_ENVIRON, 1); send_do(TELOPT_STATUS, 1); - if (env_getvalue((unsigned char *)"DISPLAY")) + if (env_getvalue((unsigned char *)"DISPLAY", 0)) send_will(TELOPT_XDISPLOC, 1); if (binary) tel_enter_binary(binary); |