diff options
author | Moritz Jodeit <moritz@cvs.openbsd.org> | 2008-09-12 16:12:09 +0000 |
---|---|---|
committer | Moritz Jodeit <moritz@cvs.openbsd.org> | 2008-09-12 16:12:09 +0000 |
commit | d5cfbc6d062d7c933a09bffc7788c32e6f24977e (patch) | |
tree | 972ce88dc630addff1ce7ba9145c1bda80e9bfdd /libexec | |
parent | 1ad9ccc3c48070cfac084feb70111a7a1d16fdb0 (diff) |
Don't split large commands into multiple commands on a 512-byte
boundary but just fail on them. This prevents CSRF-like attacks,
when a web browser is used to access an ftp server.
Reported by Maksymilian Arciemowicz <cxib@securityreason.com>.
ok millert@ martynas@
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/ftpd/extern.h | 4 | ||||
-rw-r--r-- | libexec/ftpd/ftpcmd.y | 31 | ||||
-rw-r--r-- | libexec/ftpd/ftpd.c | 11 |
3 files changed, 33 insertions, 13 deletions
diff --git a/libexec/ftpd/extern.h b/libexec/ftpd/extern.h index a4d2ba08c2e..7268cdaaadb 100644 --- a/libexec/ftpd/extern.h +++ b/libexec/ftpd/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.16 2006/04/21 17:42:50 deraadt Exp $ */ +/* $OpenBSD: extern.h,v 1.17 2008/09/12 16:12:08 moritz Exp $ */ /* $NetBSD: extern.h,v 1.2 1995/04/11 02:44:49 cgd Exp $ */ /* @@ -69,7 +69,7 @@ void dologout(int); void fatal(char *); int ftpd_pclose(FILE *); FILE *ftpd_popen(char *, char *); -char *getline(char *, int, FILE *); +int getline(char *, int, FILE *); void ftpdlogwtmp(char *, char *, char *); void lreply(int, const char *, ...); void makedir(char *); diff --git a/libexec/ftpd/ftpcmd.y b/libexec/ftpd/ftpcmd.y index 3fe95bbc392..1fda0525032 100644 --- a/libexec/ftpd/ftpcmd.y +++ b/libexec/ftpd/ftpcmd.y @@ -1,4 +1,4 @@ -/* $OpenBSD: ftpcmd.y,v 1.50 2008/06/30 12:03:51 ragge Exp $ */ +/* $OpenBSD: ftpcmd.y,v 1.51 2008/09/12 16:12:08 moritz Exp $ */ /* $NetBSD: ftpcmd.y,v 1.7 1996/04/08 19:03:11 jtc Exp $ */ /* @@ -44,7 +44,7 @@ static const char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94"; #else static const char rcsid[] = - "$OpenBSD: ftpcmd.y,v 1.50 2008/06/30 12:03:51 ragge Exp $"; + "$OpenBSD: ftpcmd.y,v 1.51 2008/09/12 16:12:08 moritz Exp $"; #endif #endif /* not lint */ @@ -1088,7 +1088,7 @@ lookup(p, cmd) /* * getline - a hacked up version of fgets to ignore TELNET escape codes. */ -char * +int getline(s, n, iop) char *s; int n; @@ -1106,7 +1106,7 @@ getline(s, n, iop) if (debug) syslog(LOG_DEBUG, "command: %s", s); tmpline[0] = '\0'; - return(s); + return(0); } if (c == 0) tmpline[0] = '\0'; @@ -1137,11 +1137,22 @@ getline(s, n, iop) } } *cs++ = c; - if (--n <= 0 || c == '\n') + if (--n <= 0) { + /* + * If command doesn't fit into buffer, discard the + * rest of the command and indicate truncation. + * This prevents the command to be split up into + * multiple commands. + */ + while ((c = getc(iop)) != EOF && c != '\n') + ; + return (-2); + } + if (c == '\n') break; } if (c == EOF && cs == s) - return (NULL); + return (-1); *cs++ = '\0'; if (debug) { if (!guest && strncasecmp("pass ", s, 5) == 0) { @@ -1161,7 +1172,7 @@ getline(s, n, iop) syslog(LOG_DEBUG, "command: %.*s", len, s); } } - return (s); + return (0); } /*ARGSUSED*/ @@ -1193,9 +1204,13 @@ yylex() case CMD: (void) alarm((unsigned) timeout); - if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) { + n = getline(cbuf, sizeof(cbuf)-1, stdin); + if (n == -1) { reply(221, "You could at least say goodbye."); dologout(0); + } else if (n == -2) { + /* Ignore truncated command */ + break; } (void) alarm(0); if ((cp = strchr(cbuf, '\r'))) { diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c index ad1f3bcb7da..2385f824c4b 100644 --- a/libexec/ftpd/ftpd.c +++ b/libexec/ftpd/ftpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ftpd.c,v 1.183 2008/06/30 12:03:51 ragge Exp $ */ +/* $OpenBSD: ftpd.c,v 1.184 2008/09/12 16:12:08 moritz Exp $ */ /* $NetBSD: ftpd.c,v 1.15 1995/06/03 22:46:47 mycroft Exp $ */ /* @@ -70,7 +70,7 @@ static const char copyright[] = static const char sccsid[] = "@(#)ftpd.c 8.4 (Berkeley) 4/16/94"; #else static const char rcsid[] = - "$OpenBSD: ftpd.c,v 1.183 2008/06/30 12:03:51 ragge Exp $"; + "$OpenBSD: ftpd.c,v 1.184 2008/09/12 16:12:08 moritz Exp $"; #endif #endif /* not lint */ @@ -2214,14 +2214,19 @@ static void myoob(void) { char *cp; + int ret; /* only process if transfer occurring */ if (!transflag) return; cp = tmpline; - if (getline(cp, 7, stdin) == NULL) { + ret = getline(cp, 7, stdin); + if (ret == -1) { reply(221, "You could at least say goodbye."); dologout(0); + } else if (ret == -2) { + /* Ignore truncated command */ + return; } upper(cp); if (strcmp(cp, "ABOR\r\n") == 0) { |